mirror of
https://github.com/openziti/ziti.git
synced 2026-10-13 07:41:17 +00:00
@@ -46,9 +46,10 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
id: setup-go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
|
||||
@@ -26,10 +26,11 @@ jobs:
|
||||
with:
|
||||
path: ziti
|
||||
|
||||
- name: Set up Go
|
||||
- name: Install Go
|
||||
id: setup-go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
|
||||
@@ -16,12 +16,13 @@ jobs:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
id: setup-go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
@@ -301,7 +301,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
@@ -416,7 +416,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v5
|
||||
|
||||
@@ -46,6 +46,12 @@ jobs:
|
||||
- name: Checkout Workspace
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
id: setup-go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Build and run a quickstart container image
|
||||
shell: bash
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.x'
|
||||
go-version-file: ./go.mod
|
||||
|
||||
- name: Install Ziti CI
|
||||
uses: openziti/ziti-ci@v1
|
||||
|
||||
+19
-17
@@ -29,20 +29,22 @@ open source that have embedded OpenZiti into the project, or use OpenZiti for se
|
||||
|
||||
Here's the list of projects which are proudly adopting and using OpenZiti
|
||||
|
||||
| Project Name | Project Link | Logo | How OpenZiti is used or why OpenZiti was chosen |
|
||||
|----------------------------------|-----------------------------------------------|----------|-----------------|
|
||||
| NetFoundry | https://nfconsole.io/signup | <img src="https://netfoundry.io/logos/Logo-Dark-Backgrounds.jpg" width="100px"> | NetFoundry SaaS provides management, orchestrations, support, and SLAs for OpenZiti networks. |
|
||||
| HackBunker | https://www.hackbunker.com/ | <img src="https://irp.cdn-website.com/b429ad92/dms3rep/multi/hackbunker+logo+new.svg" width="100px"> | To open up a Zero Trust conversation in the C-Suite and Boardrooms of Blue-chip companies with a suite of products. |
|
||||
| DeltaSecure GmbH | https://deltasecure.de/ | <img src="https://deltasecure.de/wp-content/uploads/2022/10/DeltaSecure-Logo-gross-hell.png.png" width="100px"> | To provide Managed Security Operations Center services for small and medium-sized enterprises. Ziti overlay forms the basis for secure data transmission of customer data and within the SOC infrastructure. |
|
||||
| Resulticks | https://www.resulticks.com/ | <img src="https://www.resulticks.com/assets/platform/logos/resulticks-logo-blue.svg" width="100px"> | Resulticks Zero Trust API delivery network which forms the core of Resulticks' omnichannel marketing automation platform is built on OpenZiti to form a private dark mesh network. |
|
||||
| KubeZT - Zero Trust Kubernetes | https://KubeZT.com/ | <img src="https://kubezt-public.s3-us-gov-east-1.amazonaws.com/github-org-logo.png" width="100px"> | KubeZT is an on-demand Kubernetes environment that enables developers to build and deploy highly secure applications for high-compliance organizations. |
|
||||
| Analytics HQ | https://AnalyticsHQ.com/ | <img src="https://ahq-public.s3-us-gov-west-1.amazonaws.com/ahq-logo.png" width="100px"> | Analytics HQ is a next-generation unified platform built for modern data management and advanced analytics. |
|
||||
| PITS Global Data Recovery Services | https://www.pitsdatarecovery.net/ | <img src="https://www.pitsdatarecovery.net/wp-content/uploads/2020/09/pits-logo.svg" width="100px"> | PITS Global Data Recovery Services is a data recovery company in the United States that offers services for recovering data from hard drives, SSDs, flash drives, RAID arrays and more. |
|
||||
| KEOIC | http://www.keoic.com/ | <img src="https://static.wixstatic.com/media/300f00_ebca9ecefd8743eb82769e1d3079e55a~mv2.jpg" width="100px"> | KEO International Consultants is a multifaceted AEC firm with a presence across the Middle East and Europe. KEO uses the CloudZiti platform to facilitate zero-trust connections for users, devices, and applications throughout their worldwide network of branch offices and sites. |
|
||||
| ChirpWireless | https://chirpwireless.io/ | <img src="https://docs.chirptoken.io/img/logo.svg" width="100px"> | Chirp is a project at the forefront of the DePIN (Decentralized physical infrastructure) movement, revolutionizing the world of wireless connectivity. It's a global telecommunications network that offers wireless internet and IoT connectivity for both residential and commercial use. OpenZiti overlay network is used for management of our LoRaWAN gateway miners ("Blackbirds") across multiple countries, allowing them to be dark. |
|
||||
| GIGO Dev | https://gigo.dev/ | <img src="https://gigo.dev/logo192.png" width="100px"> | GIGO Dev is a learn-to-code platform that focuses on aligning learning with the real world of development. On GIGO you work in DevSpaces (Cloud Development Environments) capable of running nearly any system configuration needed for the challenge. We use OpenZiti to dynamically and securely expose network applications inside your DevSpace. Ziti provides the simplest, easiest, and most reliable system to securely route traffic into the local network of your DevSpace. |
|
||||
| Underground Nexus | https://github.com/Underground-Ops/underground-nexus | <img src="https://raw.githubusercontent.com/Underground-Ops/underground-nexus/18d63a02aad41d8f540a044d5dd47f025d2b61a1/Graphics/SVG/cloud-underground-logo.svg" width="100px"> | Cloud Underground has chosen OpenZiti to integrate with our project called the Underground Nexus. OpenZiti provides our project with a unique way to maintain Zero Trust networking using it's overlay system to produce networks that don't require applications to be exposed to the public web - without the use of a VPN. |
|
||||
| Ubitech | https://ubitech.eu/ | <img src="https://ubitech.eu/wp-content/uploads/logo.png" width="100px"> | UBITECH develops Maestro, an end-to-end service orchestrator, which allows for seamless deployment and management of services across geo-distributed and heterogeneous domains (including 5G). Maestro uses OpenZiti as a programmable integration fabric to enable connectivity in multi-domain and multi-tenant scenarios. |
|
||||
| OSMIT GmbH | https://osmit.de/ | <img src="https://www.osmit.de/images/logo.svg" width="100px"> | OSMIT provides services for medium and large companies in the DACH region. We leverage the Zero Trust approach OpenZiti gives us to deliver our services in a secure manner to comply with data protection and privacy regulations (GDPR). |
|
||||
| Actieve | https://actieve.com/ | <img src="https://www.actieve.com/Media/Images/Logo.png" width="100px"> | Actieve provides hosting for database and web servers around the world for a variety of enterprise and small business needs. Ziti gives us the ability to grant access to services and application without the worry of exposing the services to hackers. |
|
||||
| Run Free | https://runfreeproject.com/ | <img src="https://shop.runfreeproject.com/assets/icons/apple-icon-144x144.png" width="100px"> | The Run Free Project provides a premium ecommerce experience for Run Speciaty stores. After a variety of intrusion attempts on the database and web services, Run Free implemented a Ziti only access policy for interconnecting store data and services. |
|
||||
| Project Name | Project Link | Logo | How OpenZiti is used or why OpenZiti was chosen |
|
||||
| ---------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| NetFoundry | https://nfconsole.io/signup | <img src="https://netfoundry.io/logos/Logo-Dark-Backgrounds.jpg" width="100px"> | NetFoundry SaaS provides management, orchestrations, support, and SLAs for OpenZiti networks. |
|
||||
| Rockfield IT | https://rockfieldit.com/ | <img src="https://www.rockfieldit.com/wp-content/uploads/2024/03/adopters_openziti.png" width="100px"> | Rockfield IT delivers Managed IT Services with an integrated Zero Trust approach for internal and external applications. Utilizing OpenZiti, we've enabled seamless deployment of IoT, Kubernetes, SaltStack, and Modbus, alongside empowering our field technicians with live communication tools. This ensures secure, direct data relay to our HQ via the OpenZiti overlay network during on-site diagnostics. |
|
||||
| HackBunker | https://www.hackbunker.com/ | <img src="https://irp.cdn-website.com/b429ad92/dms3rep/multi/hackbunker+logo+new.svg" width="100px"> | To open up a Zero Trust conversation in the C-Suite and Boardrooms of Blue-chip companies with a suite of products. |
|
||||
| DeltaSecure GmbH | https://deltasecure.de/ | <img src="https://deltasecure.de/wp-content/uploads/2022/10/DeltaSecure-Logo-gross-hell.png.png" width="100px"> | To provide Managed Security Operations Center services for small and medium-sized enterprises. Ziti overlay forms the basis for secure data transmission of customer data and within the SOC infrastructure. |
|
||||
| Resulticks | https://www.resulticks.com/ | <img src="https://www.resulticks.com/assets/platform/logos/resulticks-logo-blue.svg" width="100px"> | Resulticks Zero Trust API delivery network which forms the core of Resulticks' omnichannel marketing automation platform is built on OpenZiti to form a private dark mesh network. |
|
||||
| KubeZT - Zero Trust Kubernetes | https://KubeZT.com/ | <img src="https://kubezt-public.s3-us-gov-east-1.amazonaws.com/github-org-logo.png" width="100px"> | KubeZT is an on-demand Kubernetes environment that enables developers to build and deploy highly secure applications for high-compliance organizations. |
|
||||
| Analytics HQ | https://AnalyticsHQ.com/ | <img src="https://ahq-public.s3-us-gov-west-1.amazonaws.com/ahq-logo.png" width="100px"> | Analytics HQ is a next-generation unified platform built for modern data management and advanced analytics. |
|
||||
| PITS Global Data Recovery Services | https://www.pitsdatarecovery.net/ | <img src="https://www.pitsdatarecovery.net/wp-content/uploads/2020/09/pits-logo.svg" width="100px"> | PITS Global Data Recovery Services is a data recovery company in the United States that offers services for recovering data from hard drives, SSDs, flash drives, RAID arrays and more. |
|
||||
| KEOIC | http://www.keoic.com/ | <img src="https://static.wixstatic.com/media/300f00_ebca9ecefd8743eb82769e1d3079e55a~mv2.jpg" width="100px"> | KEO International Consultants is a multifaceted AEC firm with a presence across the Middle East and Europe. KEO uses the CloudZiti platform to facilitate zero-trust connections for users, devices, and applications throughout their worldwide network of branch offices and sites. |
|
||||
| ChirpWireless | https://chirpwireless.io/ | <img src="https://docs.chirptoken.io/img/logo.svg" width="100px"> | Chirp is a project at the forefront of the DePIN (Decentralized physical infrastructure) movement, revolutionizing the world of wireless connectivity. It's a global telecommunications network that offers wireless internet and IoT connectivity for both residential and commercial use. OpenZiti overlay network is used for management of our LoRaWAN gateway miners ("Blackbirds") across multiple countries, allowing them to be dark. |
|
||||
| GIGO Dev | https://gigo.dev/ | <img src="https://gigo.dev/logo192.png" width="100px"> | GIGO Dev is a learn-to-code platform that focuses on aligning learning with the real world of development. On GIGO you work in DevSpaces (Cloud Development Environments) capable of running nearly any system configuration needed for the challenge. We use OpenZiti to dynamically and securely expose network applications inside your DevSpace. Ziti provides the simplest, easiest, and most reliable system to securely route traffic into the local network of your DevSpace. |
|
||||
| Underground Nexus | https://github.com/Underground-Ops/underground-nexus | <img src="https://raw.githubusercontent.com/Underground-Ops/underground-nexus/18d63a02aad41d8f540a044d5dd47f025d2b61a1/Graphics/SVG/cloud-underground-logo.svg" width="100px"> | Cloud Underground has chosen OpenZiti to integrate with our project called the Underground Nexus. OpenZiti provides our project with a unique way to maintain Zero Trust networking using it's overlay system to produce networks that don't require applications to be exposed to the public web - without the use of a VPN. |
|
||||
| Ubitech | https://ubitech.eu/ | <img src="https://ubitech.eu/wp-content/uploads/logo.png" width="100px"> | UBITECH develops Maestro, an end-to-end service orchestrator, which allows for seamless deployment and management of services across geo-distributed and heterogeneous domains (including 5G). Maestro uses OpenZiti as a programmable integration fabric to enable connectivity in multi-domain and multi-tenant scenarios. |
|
||||
| OSMIT GmbH | https://osmit.de/ | <img src="https://www.osmit.de/images/logo.svg" width="100px"> | OSMIT provides services for medium and large companies in the DACH region. We leverage the Zero Trust approach OpenZiti gives us to deliver our services in a secure manner to comply with data protection and privacy regulations (GDPR). |
|
||||
| Actieve | https://actieve.com/ | <img src="https://www.actieve.com/Media/Images/Logo.png" width="100px"> | Actieve provides hosting for database and web servers around the world for a variety of enterprise and small business needs. Ziti gives us the ability to grant access to services and application without the worry of exposing the services to hackers. |
|
||||
| Run Free | https://runfreeproject.com/ | <img src="https://shop.runfreeproject.com/assets/icons/apple-icon-144x144.png" width="100px"> | The Run Free Project provides a premium ecommerce experience for Run Speciaty stores. After a variety of intrusion attempts on the database and web services, Run Free implemented a Ziti only access policy for interconnecting store data and services. |
|
||||
| grc4cisc | https://grc4ciso.com/ | <img src="https://grc4ciso.com/assets/img/logo_1.png" width="100px"> | grc4ciso is a SaaS platform that unifies the functionalities of a XDR + GRC + ZeroTrust. Zero Trust is based on OpenZiti, providing overlay network components necessary to integrate zero trust into small and medium-sized companies. |
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
# Release 0.34.2
|
||||
|
||||
## What's New
|
||||
|
||||
* The circuit id is now available in the SDK on the client and hosting side
|
||||
* Requires 0.34.2+ routers
|
||||
* Requests SDK support. Currently supported in the Go SDK 0.23.11+
|
||||
* Bug fixes
|
||||
|
||||
## Component Updates and Bug Fixes
|
||||
* github.com/openziti/edge-api: [v0.26.13 -> v0.26.14](https://github.com/openziti/edge-api/compare/v0.26.13...v0.26.14)
|
||||
* github.com/openziti/sdk-golang: [v0.23.14 -> v0.23.15](https://github.com/openziti/sdk-golang/compare/v0.23.14...v0.23.15)
|
||||
* github.com/openziti/secretstream: [v0.1.17 -> v0.1.18](https://github.com/openziti/secretstream/compare/v0.1.17...v0.1.18)
|
||||
* [Issue #24](https://github.com/openziti/secretstream/issues/24) - Potential side channel issue
|
||||
* [Issue #25](https://github.com/openziti/secretstream/issues/25) - Reads from crypto/rand not checked for errors
|
||||
|
||||
* github.com/openziti/ziti: [v0.34.1 -> v0.34.2](https://github.com/openziti/ziti/compare/v0.34.1...v0.34.2)
|
||||
* [Issue #1831](https://github.com/openziti/ziti/issues/1831) - Circuit ID should be returned in the response to a Dial request
|
||||
* [Issue #1873](https://github.com/openziti/ziti/issues/1873) - host.v1 health check time.Duration unconvertible
|
||||
|
||||
# Release 0.34.1
|
||||
|
||||
## What's New
|
||||
|
||||
+1015
-855
File diff suppressed because it is too large
Load Diff
@@ -175,6 +175,16 @@ message Controller {
|
||||
bool isOnline = 6;
|
||||
google.protobuf.Timestamp lastJoinedAt = 7;
|
||||
map<string, TagValue> tags = 8;
|
||||
map<string,ApiAddressList> apiAddresses = 9;
|
||||
}
|
||||
|
||||
message ApiAddressList {
|
||||
repeated ApiAddress addresses = 1;
|
||||
}
|
||||
|
||||
message ApiAddress {
|
||||
string Url = 1;
|
||||
string Version = 2;
|
||||
}
|
||||
|
||||
// Edge Routers
|
||||
|
||||
@@ -417,6 +417,10 @@ func (rdm *RouterDataModel) ApplyRevocationEvent(event *edge_ctrl_pb.DataState_E
|
||||
rdm.sendEvent(event)
|
||||
}
|
||||
|
||||
func (rdm *RouterDataModel) GetPublicKeys() map[string]*edge_ctrl_pb.DataState_PublicKey {
|
||||
return rdm.PublicKeys.Items()
|
||||
}
|
||||
|
||||
func (rdm *RouterDataModel) GetDataState() *edge_ctrl_pb.DataState {
|
||||
var events []*edge_ctrl_pb.DataState_Event
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/openziti/ziti/controller/zac"
|
||||
"math/big"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
@@ -85,6 +86,10 @@ type Controller struct {
|
||||
metricsRegistry metrics.Registry
|
||||
versionProvider versions.VersionProvider
|
||||
eventDispatcher *events.Dispatcher
|
||||
|
||||
apiData map[string][]event.ApiAddress
|
||||
apiDataBytes []byte
|
||||
apiDataOnce sync.Once
|
||||
}
|
||||
|
||||
func (c *Controller) GetPeerSigners() []*x509.Certificate {
|
||||
@@ -154,6 +159,15 @@ func (c *Controller) GetRaftIndex() uint64 {
|
||||
return c.raftController.Raft.LastIndex()
|
||||
}
|
||||
|
||||
func (c *Controller) GetRaftInfo() (string, string, string) {
|
||||
id := c.config.Id.Token
|
||||
addr := c.raftController.Mesh.Addr().String()
|
||||
|
||||
version := c.GetVersionProvider().Version()
|
||||
|
||||
return string(addr), string(id), version
|
||||
}
|
||||
|
||||
func (c *Controller) GetDb() boltz.Db {
|
||||
return c.config.Db
|
||||
}
|
||||
@@ -338,7 +352,11 @@ func (c *Controller) Run() error {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go c.xweb.Run()
|
||||
c.xweb.Run()
|
||||
|
||||
for _, helloHeader := range c.GetHelloHeaderProviders() {
|
||||
helloHeader.Apply(headers)
|
||||
}
|
||||
|
||||
// event handlers
|
||||
if err := c.eventDispatcher.WireEventHandlers(c.getEventHandlerConfigs()); err != nil {
|
||||
@@ -562,3 +580,55 @@ func (c *Controller) InitializeRaftFromBoltDb(sourceDbPath string) error {
|
||||
|
||||
return c.raftController.Dispatch(cmd)
|
||||
}
|
||||
|
||||
// TODO: this functions is a temporary hack and should be provided by xweb
|
||||
func getApiPath(binding string) string {
|
||||
switch binding {
|
||||
case "edge-client":
|
||||
return "/edge/client/v1"
|
||||
case "edge-management":
|
||||
return "/edge/management/v1"
|
||||
case "fabric":
|
||||
return "/fabric/v1"
|
||||
case "health-checks":
|
||||
return "health-checks"
|
||||
case "edge-oidc":
|
||||
return "/oidc"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Controller) GetApiAddresses() (map[string][]event.ApiAddress, []byte) {
|
||||
c.apiDataOnce.Do(func() {
|
||||
xwebConfig := c.xweb.GetConfig()
|
||||
|
||||
apiData := map[string][]event.ApiAddress{}
|
||||
for _, serverConfig := range xwebConfig.ServerConfigs {
|
||||
for _, bindPoint := range serverConfig.BindPoints {
|
||||
for _, api := range serverConfig.APIs {
|
||||
apiData[api.Binding()] = append(apiData[api.Binding()], event.ApiAddress{
|
||||
Url: "https://" + bindPoint.Address + getApiPath(api.Binding()), //TODO: temp till xweb support reporting API paths
|
||||
Version: "v1", //TODO: temp till xweb supports reporting versions via api.Version()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.apiData = apiData
|
||||
c.apiDataBytes, _ = json.Marshal(apiData)
|
||||
})
|
||||
|
||||
return c.apiData, c.apiDataBytes
|
||||
}
|
||||
|
||||
func (c *Controller) GetHelloHeaderProviders() []mesh.HeaderProvider {
|
||||
providerFunc := func(headers map[int32][]byte) {
|
||||
_, apiDataBytes := c.GetApiAddresses()
|
||||
|
||||
headers[mesh.ApiAddressesHeader] = apiDataBytes
|
||||
}
|
||||
|
||||
provider := mesh.HeaderProviderFunc(providerFunc)
|
||||
return []mesh.HeaderProvider{provider}
|
||||
}
|
||||
|
||||
@@ -19,25 +19,35 @@ package db
|
||||
import (
|
||||
"github.com/openziti/storage/ast"
|
||||
"github.com/openziti/storage/boltz"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
FieldControllerAddress = "address"
|
||||
FieldControllerCertPem = "certPem"
|
||||
FieldControllerFingerprint = "fingerprint"
|
||||
FieldControllerIsOnline = "isOnline"
|
||||
FieldControllerLastJoinedAt = "lastJoinedAt"
|
||||
FieldControllerCtrlAddress = "ctrlAddress"
|
||||
FieldControllerCertPem = "certPem"
|
||||
FieldControllerFingerprint = "fingerprint"
|
||||
FieldControllerIsOnline = "isOnline"
|
||||
FieldControllerLastJoinedAt = "lastJoinedAt"
|
||||
FieldControllerApiAddresses = "apiAddresses"
|
||||
FieldControllerApiAddressVersion = "apiAddresses.version"
|
||||
FieldControllerApiAddressUrl = "apiAddresses.url"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
boltz.BaseExtEntity
|
||||
Name string `json:"name"`
|
||||
Address string `json:"address"`
|
||||
CtrlAddress string `json:"address"`
|
||||
CertPem string `json:"certPem"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
IsOnline bool `json:"isOnline"`
|
||||
LastJoinedAt *time.Time `json:"lastJoinedAt"`
|
||||
ApiAddresses map[string][]ApiAddress
|
||||
}
|
||||
|
||||
type ApiAddress struct {
|
||||
Url string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func (entity *Controller) GetName() string {
|
||||
@@ -75,7 +85,7 @@ func (store *controllerStoreImpl) initializeLocal() {
|
||||
store.AddExtEntitySymbols()
|
||||
store.indexName = store.addUniqueNameField()
|
||||
|
||||
store.AddSymbol(FieldControllerAddress, ast.NodeTypeString)
|
||||
store.AddSymbol(FieldControllerCtrlAddress, ast.NodeTypeString)
|
||||
store.AddSymbol(FieldControllerCertPem, ast.NodeTypeString)
|
||||
store.AddSymbol(FieldControllerFingerprint, ast.NodeTypeString)
|
||||
store.AddSymbol(FieldControllerIsOnline, ast.NodeTypeBool)
|
||||
@@ -91,19 +101,58 @@ func (store *controllerStoreImpl) NewEntity() *Controller {
|
||||
func (store *controllerStoreImpl) FillEntity(entity *Controller, bucket *boltz.TypedBucket) {
|
||||
entity.LoadBaseValues(bucket)
|
||||
entity.Name = bucket.GetStringOrError(FieldName)
|
||||
entity.Address = bucket.GetStringWithDefault(FieldControllerAddress, "")
|
||||
entity.CtrlAddress = bucket.GetStringWithDefault(FieldControllerCtrlAddress, "")
|
||||
entity.CertPem = bucket.GetStringOrError(FieldControllerCertPem)
|
||||
entity.Fingerprint = bucket.GetStringOrError(FieldControllerFingerprint)
|
||||
entity.IsOnline = bucket.GetBoolWithDefault(FieldControllerIsOnline, false)
|
||||
entity.LastJoinedAt = bucket.GetTime(FieldControllerLastJoinedAt)
|
||||
entity.ApiAddresses = map[string][]ApiAddress{}
|
||||
|
||||
apiListBucket := bucket.GetBucket(FieldControllerApiAddresses)
|
||||
if apiListBucket != nil {
|
||||
apiListCursor := apiListBucket.Cursor()
|
||||
|
||||
for apiKey, _ := apiListCursor.First(); apiKey != nil; apiKey, _ = apiListCursor.Next() {
|
||||
apiBucket := apiListBucket.GetBucket(string(apiKey))
|
||||
|
||||
if apiBucket != nil {
|
||||
entity.ApiAddresses[string(apiKey)] = nil
|
||||
instanceCursor := apiBucket.Cursor()
|
||||
|
||||
for instanceKey, _ := instanceCursor.First(); instanceKey != nil; instanceKey, _ = instanceCursor.Next() {
|
||||
instance := apiBucket.GetBucket(string(instanceKey))
|
||||
|
||||
if instance != nil {
|
||||
newInstance := ApiAddress{
|
||||
Url: instance.GetStringWithDefault(FieldControllerApiAddressUrl, ""),
|
||||
Version: instance.GetStringWithDefault(FieldControllerApiAddressVersion, ""),
|
||||
}
|
||||
entity.ApiAddresses[string(apiKey)] = append(entity.ApiAddresses[string(apiKey)], newInstance)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (store *controllerStoreImpl) PersistEntity(entity *Controller, ctx *boltz.PersistContext) {
|
||||
entity.SetBaseValues(ctx)
|
||||
ctx.SetString(FieldName, entity.Name)
|
||||
ctx.SetString(FieldControllerAddress, entity.Address)
|
||||
ctx.SetString(FieldControllerCtrlAddress, entity.CtrlAddress)
|
||||
ctx.SetString(FieldControllerCertPem, entity.CertPem)
|
||||
ctx.SetString(FieldControllerFingerprint, entity.Fingerprint)
|
||||
ctx.SetBool(FieldControllerIsOnline, entity.IsOnline)
|
||||
ctx.SetTimeP(FieldControllerLastJoinedAt, entity.LastJoinedAt)
|
||||
|
||||
apiListBucket := ctx.Bucket.GetOrCreateBucket(FieldControllerApiAddresses)
|
||||
|
||||
for apiKey, apis := range entity.ApiAddresses {
|
||||
apiBucket, _ := apiListBucket.EmptyBucket(apiKey)
|
||||
for i, instance := range apis {
|
||||
instanceBucket := apiBucket.GetOrCreateBucket(strconv.Itoa(i))
|
||||
|
||||
instanceBucket.SetString(FieldControllerApiAddressUrl, instance.Url, ctx.FieldChecker)
|
||||
instanceBucket.SetString(FieldControllerApiAddressVersion, instance.Version, ctx.FieldChecker)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+12
-22
@@ -314,6 +314,8 @@ type HostController interface {
|
||||
GetEventDispatcher() event.Dispatcher
|
||||
GetRaftIndex() uint64
|
||||
GetPeerAddresses() []string
|
||||
GetRaftInfo() (string, string, string)
|
||||
GetApiAddresses() (map[string][]event.ApiAddress, []byte)
|
||||
}
|
||||
|
||||
type Schemes struct {
|
||||
@@ -830,29 +832,19 @@ func (ae *AppEnv) ControllersKeyFunc(token *jwt.Token) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return ae.GetControllerPublicKey(kid), nil
|
||||
key := ae.GetControllerPublicKey(kid)
|
||||
|
||||
if key == nil {
|
||||
return nil, fmt.Errorf("key for kid %s, not found", kid)
|
||||
}
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (ae *AppEnv) GetControllerPublicKey(kid string) crypto.PublicKey {
|
||||
serverTlsCert, serverKid, _ := ae.GetServerCert()
|
||||
signers := ae.GetHostController().GetPeerSigners()
|
||||
|
||||
kids := map[string]crypto.PublicKey{
|
||||
serverKid: serverTlsCert.Leaf.PublicKey,
|
||||
}
|
||||
|
||||
for _, signer := range signers {
|
||||
signerKid := fmt.Sprintf("%s", sha1.Sum(signer.Raw))
|
||||
kids[signerKid] = signer.PublicKey
|
||||
}
|
||||
|
||||
for curKid, publicKey := range kids {
|
||||
if curKid == kid {
|
||||
return publicKey
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
signers := ae.Broker.GetPublicKeys()
|
||||
pfxlog.Logger().Info("looking for signer: " + kid)
|
||||
return signers[kid]
|
||||
}
|
||||
|
||||
func (ae *AppEnv) CreateRequestContext(rw http.ResponseWriter, r *http.Request) *response.RequestContext {
|
||||
@@ -967,8 +959,6 @@ func (ae *AppEnv) SetServerCert(serverCert *tls.Certificate) {
|
||||
signMethod := getJwtSigningMethod(serverCert)
|
||||
kid := fmt.Sprintf("%x", sha1.Sum(serverCert.Certificate[0]))
|
||||
ae.serverSigner = jwtsigner.New(signMethod, serverCert.PrivateKey, kid)
|
||||
|
||||
ae.Broker.routerSyncStrategy.AddPublicKey(ae.ServerCert)
|
||||
}
|
||||
|
||||
func (ae *AppEnv) OidcIssuer() string {
|
||||
|
||||
Vendored
+51
-6
@@ -17,6 +17,8 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"github.com/michaelquigley/pfxlog"
|
||||
"github.com/openziti/channel/v2"
|
||||
"github.com/openziti/storage/boltz"
|
||||
@@ -25,6 +27,7 @@ import (
|
||||
"github.com/openziti/ziti/controller/event"
|
||||
"github.com/openziti/ziti/controller/network"
|
||||
"go.etcd.io/bbolt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -57,6 +60,9 @@ type Broker struct {
|
||||
apiSessionChunkSize int
|
||||
routerMsgBufferSize int
|
||||
routerSyncStrategy RouterSyncStrategy
|
||||
|
||||
publicKeyLock sync.Mutex
|
||||
publicKeys map[string]crypto.PublicKey
|
||||
}
|
||||
|
||||
func NewBroker(ae *AppEnv, synchronizer RouterSyncStrategy) *Broker {
|
||||
@@ -73,13 +79,11 @@ func NewBroker(ae *AppEnv, synchronizer RouterSyncStrategy) *Broker {
|
||||
broker.ae.GetStores().ApiSession.GetEventsEmitter().AddListener(db.EventFullyAuthenticated, broker.apiSessionFullyAuthenticated)
|
||||
broker.ae.GetStores().ApiSessionCertificate.AddEntityEventListenerF(broker.apiSessionCertificateCreated, boltz.EntityCreatedAsync)
|
||||
broker.ae.GetStores().ApiSessionCertificate.AddEntityEventListenerF(broker.apiSessionCertificateDeleted, boltz.EntityDeletedAsync)
|
||||
broker.ae.GetStores().Controller.AddEntityEventListenerF(broker.controllerAdded, boltz.EntityCreated)
|
||||
broker.ae.GetStores().Controller.AddEntityEventListenerF(broker.controllerAdded, boltz.EntityUpdated)
|
||||
|
||||
ae.HostController.GetNetwork().AddRouterPresenceHandler(broker)
|
||||
ae.HostController.GetEventDispatcher().AddClusterEventHandler(broker)
|
||||
|
||||
ae.GetHostController().GetPeerSigners()
|
||||
//updates controller store on leader, store update trigger strategy in all controllers
|
||||
ae.HostController.GetEventDispatcher().AddClusterEventHandler(broker)
|
||||
|
||||
return broker
|
||||
}
|
||||
@@ -187,6 +191,47 @@ func (broker *Broker) Stop() {
|
||||
broker.routerSyncStrategy.Stop()
|
||||
}
|
||||
|
||||
func (broker *Broker) controllerAdded(controller *db.Controller) {
|
||||
broker.routerSyncStrategy.PeerAdded(controller)
|
||||
func (broker *Broker) GetPublicKeys() map[string]crypto.PublicKey {
|
||||
broker.publicKeyLock.Lock()
|
||||
defer broker.publicKeyLock.Unlock()
|
||||
|
||||
if broker.publicKeys == nil {
|
||||
broker.publicKeys = map[string]crypto.PublicKey{}
|
||||
}
|
||||
|
||||
for kid, pubKey := range broker.routerSyncStrategy.GetPublicKeys() {
|
||||
//don't reprocess the same kid
|
||||
if _, exists := broker.publicKeys[kid]; exists {
|
||||
continue
|
||||
}
|
||||
log := pfxlog.Logger().WithField("format", pubKey.Format).WithField("kid", kid)
|
||||
|
||||
switch pubKey.Format {
|
||||
case edge_ctrl_pb.DataState_PublicKey_X509CertDer:
|
||||
cert, err := x509.ParseCertificate(pubKey.GetData())
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error parsing x509 certificate DER")
|
||||
continue
|
||||
}
|
||||
|
||||
broker.publicKeys[kid] = cert.PublicKey
|
||||
case edge_ctrl_pb.DataState_PublicKey_PKIXPublicKey:
|
||||
pub, err := x509.ParsePKIXPublicKey(pubKey.GetData())
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error parsing PKIX public key DER")
|
||||
continue
|
||||
}
|
||||
broker.publicKeys[kid] = pub
|
||||
default:
|
||||
log.Error("unknown public key format")
|
||||
}
|
||||
}
|
||||
|
||||
result := map[string]crypto.PublicKey{}
|
||||
|
||||
for k, v := range broker.publicKeys {
|
||||
result[k] = v
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Vendored
+2
-5
@@ -17,9 +17,9 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"github.com/openziti/channel/v2"
|
||||
"github.com/openziti/foundation/v2/versions"
|
||||
"github.com/openziti/ziti/common/pb/edge_ctrl_pb"
|
||||
"github.com/openziti/ziti/controller/db"
|
||||
"github.com/openziti/ziti/controller/model"
|
||||
"github.com/openziti/ziti/controller/network"
|
||||
@@ -59,9 +59,9 @@ type RouterSyncStrategy interface {
|
||||
Type() RouterSyncStrategyType
|
||||
GetEdgeRouterState(id string) RouterStateValues
|
||||
Stop()
|
||||
GetPublicKeys() map[string]*edge_ctrl_pb.DataState_PublicKey
|
||||
RouterConnectionHandler
|
||||
RouterSynchronizerEventHandler
|
||||
AddPublicKey(cert *tls.Certificate)
|
||||
}
|
||||
|
||||
// RouterConnectionHandler is responsible for handling router connect/disconnect for synchronizing state.
|
||||
@@ -78,10 +78,7 @@ type RouterSynchronizerEventHandler interface {
|
||||
ApiSessionAdded(apiSession *db.ApiSession)
|
||||
ApiSessionUpdated(apiSession *db.ApiSession, apiSessionCert *db.ApiSessionCertificate)
|
||||
ApiSessionDeleted(apiSession *db.ApiSession)
|
||||
|
||||
SessionDeleted(session *db.Session)
|
||||
|
||||
PeerAdded(*db.Controller)
|
||||
}
|
||||
|
||||
// RouterState provides a thread save mechanism to access and set router status information that may be influx
|
||||
|
||||
@@ -37,10 +37,16 @@ const (
|
||||
)
|
||||
|
||||
type ClusterPeer struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
Addr string `json:"addr,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
ServerCert []*x509.Certificate `json:"-"`
|
||||
Id string `json:"id,omitempty"`
|
||||
Addr string `json:"addr,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
ServerCert []*x509.Certificate `json:"-"`
|
||||
ApiAddresses map[string][]ApiAddress `json:"apiAddresses"`
|
||||
}
|
||||
|
||||
type ApiAddress struct {
|
||||
Url string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func (self *ClusterPeer) String() string {
|
||||
|
||||
@@ -18,6 +18,7 @@ package routes
|
||||
|
||||
import (
|
||||
"github.com/openziti/edge-api/rest_model"
|
||||
edgeController "github.com/openziti/ziti/controller"
|
||||
"github.com/openziti/ziti/controller/env"
|
||||
"github.com/openziti/ziti/controller/model"
|
||||
"github.com/openziti/ziti/controller/response"
|
||||
@@ -27,23 +28,56 @@ const EntityNameController = "controllers"
|
||||
|
||||
var ControllerLinkFactory = NewBasicLinkFactory(EntityNameController)
|
||||
|
||||
func MapControllerToRestEntity(_ *env.AppEnv, _ *response.RequestContext, Controller *model.Controller) (interface{}, error) {
|
||||
return MapControllerToRestModel(Controller)
|
||||
func MapControllerToManagementRestEntity(_ *env.AppEnv, _ *response.RequestContext, Controller *model.Controller) (interface{}, error) {
|
||||
return MapControllerToManagementRestModel(Controller)
|
||||
}
|
||||
|
||||
func MapControllerToRestModel(controller *model.Controller) (*rest_model.ControllerDetail, error) {
|
||||
func MapControllerToClientRestEntity(_ *env.AppEnv, _ *response.RequestContext, Controller *model.Controller) (interface{}, error) {
|
||||
return MapControllerToClientRestModel(Controller)
|
||||
}
|
||||
|
||||
func MapControllerToManagementRestModel(controller *model.Controller) (*rest_model.ControllerDetail, error) {
|
||||
ret := &rest_model.ControllerDetail{
|
||||
BaseEntity: BaseEntityToRestModel(controller, ControllerLinkFactory),
|
||||
Name: &controller.Name,
|
||||
Address: &controller.Address,
|
||||
CertPem: &controller.CertPem,
|
||||
Fingerprint: &controller.Fingerprint,
|
||||
IsOnline: &controller.IsOnline,
|
||||
BaseEntity: BaseEntityToRestModel(controller, ControllerLinkFactory),
|
||||
Name: &controller.Name,
|
||||
CtrlAddress: &controller.CtrlAddress,
|
||||
APIAddresses: rest_model.APIAddressList{},
|
||||
CertPem: &controller.CertPem,
|
||||
Fingerprint: &controller.Fingerprint,
|
||||
IsOnline: &controller.IsOnline,
|
||||
}
|
||||
|
||||
if controller.LastJoinedAt != nil {
|
||||
ret.LastJoinedAt = toStrFmtDateTimeP(*controller.LastJoinedAt)
|
||||
}
|
||||
|
||||
for apiKey, instances := range controller.ApiAddresses {
|
||||
ret.APIAddresses[apiKey] = rest_model.APIAddressArray{}
|
||||
|
||||
for _, instance := range instances {
|
||||
ret.APIAddresses[apiKey] = append(ret.APIAddresses[apiKey], &rest_model.APIAddress{
|
||||
URL: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func MapControllerToClientRestModel(controller *model.Controller) (*rest_model.ControllerDetail, error) {
|
||||
ret, err := MapControllerToManagementRestModel(controller)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret.CtrlAddress = nil
|
||||
|
||||
for apiKey := range ret.APIAddresses {
|
||||
if apiKey != edgeController.ClientApiBinding && apiKey != edgeController.OidcApiBinding {
|
||||
delete(ret.APIAddresses, apiKey)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -43,14 +43,18 @@ func NewControllerRouter() *ControllerRouter {
|
||||
|
||||
func (r *ControllerRouter) Register(ae *env.AppEnv) {
|
||||
ae.ManagementApi.ControllersListControllersHandler = controllersMan.ListControllersHandlerFunc(func(params controllersMan.ListControllersParams, _ interface{}) middleware.Responder {
|
||||
return ae.IsAllowed(r.List, params.HTTPRequest, "", "", permissions.IsAdmin())
|
||||
return ae.IsAllowed(r.ListManagement, params.HTTPRequest, "", "", permissions.IsAuthenticated())
|
||||
})
|
||||
|
||||
ae.ClientApi.ControllersListControllersHandler = controllersClient.ListControllersHandlerFunc(func(params controllersClient.ListControllersParams, _ interface{}) middleware.Responder {
|
||||
return ae.IsAllowed(r.List, params.HTTPRequest, "", "", permissions.IsAdmin())
|
||||
return ae.IsAllowed(r.ListClient, params.HTTPRequest, "", "", permissions.IsAuthenticated())
|
||||
})
|
||||
}
|
||||
|
||||
func (r *ControllerRouter) List(ae *env.AppEnv, rc *response.RequestContext) {
|
||||
ListWithHandler[*model.Controller](ae, rc, ae.Managers.Controller, MapControllerToRestEntity)
|
||||
func (r *ControllerRouter) ListManagement(ae *env.AppEnv, rc *response.RequestContext) {
|
||||
ListWithHandler[*model.Controller](ae, rc, ae.Managers.Controller, MapControllerToManagementRestEntity)
|
||||
}
|
||||
|
||||
func (r *ControllerRouter) ListClient(ae *env.AppEnv, rc *response.RequestContext) {
|
||||
ListWithHandler[*model.Controller](ae, rc, ae.Managers.Controller, MapControllerToClientRestEntity)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"github.com/michaelquigley/pfxlog"
|
||||
nfpem "github.com/openziti/foundation/v2/pem"
|
||||
"github.com/openziti/foundation/v2/stringz"
|
||||
@@ -117,11 +118,22 @@ func (self *ControllerManager) Marshall(entity *Controller) ([]byte, error) {
|
||||
msg := &edge_cmd_pb.Controller{
|
||||
Id: entity.Id,
|
||||
Name: entity.Name,
|
||||
Address: entity.Address,
|
||||
Address: entity.CtrlAddress,
|
||||
CertPem: entity.CertPem,
|
||||
Fingerprint: entity.Fingerprint,
|
||||
IsOnline: entity.IsOnline,
|
||||
LastJoinedAt: timePtrToPb(entity.LastJoinedAt),
|
||||
ApiAddresses: map[string]*edge_cmd_pb.ApiAddressList{},
|
||||
}
|
||||
|
||||
for apiKey, instances := range entity.ApiAddresses {
|
||||
msg.ApiAddresses[apiKey] = &edge_cmd_pb.ApiAddressList{}
|
||||
for _, instance := range instances {
|
||||
msg.ApiAddresses[apiKey].Addresses = append(msg.ApiAddresses[apiKey].Addresses, &edge_cmd_pb.ApiAddress{
|
||||
Url: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return proto.Marshal(msg)
|
||||
@@ -134,18 +146,57 @@ func (self *ControllerManager) Unmarshall(bytes []byte) (*Controller, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Controller{
|
||||
controller := &Controller{
|
||||
BaseEntity: models.BaseEntity{
|
||||
Id: msg.Id,
|
||||
Tags: edge_cmd_pb.DecodeTags(msg.Tags),
|
||||
},
|
||||
Name: msg.Name,
|
||||
Address: msg.Address,
|
||||
CtrlAddress: msg.Address,
|
||||
CertPem: msg.CertPem,
|
||||
Fingerprint: msg.Fingerprint,
|
||||
IsOnline: msg.IsOnline,
|
||||
LastJoinedAt: pbTimeToTimePtr(msg.LastJoinedAt),
|
||||
}, nil
|
||||
ApiAddresses: map[string][]ApiAddress{},
|
||||
}
|
||||
|
||||
for apiKey, instanceList := range msg.ApiAddresses {
|
||||
controller.ApiAddresses[apiKey] = nil
|
||||
if instanceList != nil {
|
||||
for _, instance := range instanceList.Addresses {
|
||||
controller.ApiAddresses[apiKey] = append(controller.ApiAddresses[apiKey], ApiAddress{
|
||||
Url: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return controller, nil
|
||||
}
|
||||
|
||||
func (self *ControllerManager) getCurrentAsClusterPeer() *event.ClusterPeer {
|
||||
addr, id, version := self.env.GetHostController().GetRaftInfo()
|
||||
tlsConfig, _, _ := self.env.GetServerCert()
|
||||
var leaderCerts []*x509.Certificate
|
||||
|
||||
for _, certBytes := range tlsConfig.Certificate {
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
|
||||
if err == nil {
|
||||
leaderCerts = append(leaderCerts, cert)
|
||||
}
|
||||
}
|
||||
|
||||
apiAddresses, _ := self.env.GetHostController().GetApiAddresses()
|
||||
|
||||
return &event.ClusterPeer{
|
||||
Id: id,
|
||||
Addr: addr,
|
||||
Version: version,
|
||||
ServerCert: leaderCerts,
|
||||
ApiAddresses: apiAddresses,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *ControllerManager) PeersConnected(peers []*event.ClusterPeer) {
|
||||
@@ -165,27 +216,58 @@ func (self *ControllerManager) PeersConnected(peers []*event.ClusterPeer) {
|
||||
}
|
||||
|
||||
connectFields := fields.UpdatedFieldsMap{
|
||||
db.FieldControllerLastJoinedAt: struct{}{},
|
||||
db.FieldControllerCertPem: struct{}{},
|
||||
db.FieldControllerFingerprint: struct{}{},
|
||||
db.FieldControllerIsOnline: struct{}{},
|
||||
db.FieldControllerAddress: struct{}{},
|
||||
db.FieldControllerLastJoinedAt: struct{}{},
|
||||
db.FieldControllerCertPem: struct{}{},
|
||||
db.FieldControllerFingerprint: struct{}{},
|
||||
db.FieldControllerIsOnline: struct{}{},
|
||||
db.FieldControllerCtrlAddress: struct{}{},
|
||||
db.FieldControllerApiAddresses: struct{}{},
|
||||
db.FieldControllerApiAddressUrl: struct{}{},
|
||||
db.FieldControllerApiAddressVersion: struct{}{},
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
selfAsPeer := self.getCurrentAsClusterPeer()
|
||||
peerFingerprints := ""
|
||||
for _, peer := range peers {
|
||||
fingerprint := nfpem.FingerprintFromCertificate(peer.ServerCert[0])
|
||||
|
||||
if peerFingerprints == "" {
|
||||
peerFingerprints = fingerprint
|
||||
} else {
|
||||
peerFingerprints = peerFingerprints + ", " + fingerprint
|
||||
}
|
||||
}
|
||||
|
||||
pfxlog.Logger().Infof("acting as leader, updating controllers with peers, self: %s, peers: %s", nfpem.FingerprintFromCertificate(selfAsPeer.ServerCert[0]), peerFingerprints)
|
||||
|
||||
// always as this controller as a "peer" to add or update on the controller list
|
||||
peers = append(peers, selfAsPeer)
|
||||
|
||||
for _, peer := range peers {
|
||||
if stringz.Contains(controllerIds, peer.Id) {
|
||||
existing, err := self.Read(peer.Id)
|
||||
|
||||
if err != nil {
|
||||
pfxlog.Logger().WithError(err).Error("could not handle new peer(s) connection, existing controller could not be read")
|
||||
continue
|
||||
}
|
||||
|
||||
existing.Address = peer.Addr
|
||||
existing.CtrlAddress = peer.Addr
|
||||
existing.IsOnline = true
|
||||
existing.LastJoinedAt = &now
|
||||
existing.ApiAddresses = map[string][]ApiAddress{}
|
||||
|
||||
for apiKey, instances := range peer.ApiAddresses {
|
||||
existing.ApiAddresses[apiKey] = nil
|
||||
|
||||
for _, instance := range instances {
|
||||
existing.ApiAddresses[apiKey] = append(existing.ApiAddresses[apiKey], ApiAddress{
|
||||
Url: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(peer.ServerCert) > 0 {
|
||||
existing.CertPem = nfpem.EncodeToString(peer.ServerCert[0])
|
||||
@@ -205,11 +287,22 @@ func (self *ControllerManager) PeersConnected(peers []*event.ClusterPeer) {
|
||||
BaseEntity: models.BaseEntity{
|
||||
Id: peer.Id,
|
||||
},
|
||||
Address: peer.Addr,
|
||||
CtrlAddress: peer.Addr,
|
||||
IsOnline: true,
|
||||
LastJoinedAt: &now,
|
||||
}
|
||||
|
||||
for apiKey, instances := range peer.ApiAddresses {
|
||||
newController.ApiAddresses[apiKey] = nil
|
||||
|
||||
for _, instance := range instances {
|
||||
newController.ApiAddresses[apiKey] = append(newController.ApiAddresses[apiKey], ApiAddress{
|
||||
Url: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
newController.Name = peer.ServerCert[0].Subject.CommonName
|
||||
newController.CertPem = nfpem.EncodeToString(peer.ServerCert[0])
|
||||
newController.Fingerprint = nfpem.FingerprintFromCertificate(peer.ServerCert[0])
|
||||
|
||||
@@ -27,22 +27,39 @@ import (
|
||||
type Controller struct {
|
||||
models.BaseEntity
|
||||
Name string
|
||||
Address string
|
||||
CtrlAddress string
|
||||
CertPem string
|
||||
Fingerprint string
|
||||
IsOnline bool
|
||||
LastJoinedAt *time.Time
|
||||
ApiAddresses map[string][]ApiAddress
|
||||
}
|
||||
|
||||
type ApiAddress struct {
|
||||
Url string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func (entity *Controller) toBoltEntity(tx *bbolt.Tx, env Env) (*db.Controller, error) {
|
||||
boltEntity := &db.Controller{
|
||||
BaseExtEntity: *boltz.NewExtEntity(entity.Id, entity.Tags),
|
||||
Name: entity.Name,
|
||||
Address: entity.Address,
|
||||
CtrlAddress: entity.CtrlAddress,
|
||||
CertPem: entity.CertPem,
|
||||
Fingerprint: entity.Fingerprint,
|
||||
IsOnline: entity.IsOnline,
|
||||
LastJoinedAt: entity.LastJoinedAt,
|
||||
ApiAddresses: map[string][]db.ApiAddress{},
|
||||
}
|
||||
|
||||
for apiKey, instances := range entity.ApiAddresses {
|
||||
boltEntity.ApiAddresses[apiKey] = nil
|
||||
for _, instance := range instances {
|
||||
boltEntity.ApiAddresses[apiKey] = append(boltEntity.ApiAddresses[apiKey], db.ApiAddress{
|
||||
Url: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return boltEntity, nil
|
||||
@@ -59,11 +76,22 @@ func (entity *Controller) toBoltEntityForUpdate(tx *bbolt.Tx, env Env, _ boltz.F
|
||||
func (entity *Controller) fillFrom(env Env, tx *bbolt.Tx, boltController *db.Controller) error {
|
||||
entity.FillCommon(boltController)
|
||||
entity.Name = boltController.Name
|
||||
entity.Address = boltController.Address
|
||||
entity.CtrlAddress = boltController.CtrlAddress
|
||||
entity.CertPem = boltController.CertPem
|
||||
entity.Fingerprint = boltController.Fingerprint
|
||||
entity.IsOnline = boltController.IsOnline
|
||||
entity.LastJoinedAt = boltController.LastJoinedAt
|
||||
entity.ApiAddresses = map[string][]ApiAddress{}
|
||||
|
||||
for apiKey, instances := range boltController.ApiAddresses {
|
||||
entity.ApiAddresses[apiKey] = nil
|
||||
for _, instance := range instances {
|
||||
entity.ApiAddresses[apiKey] = append(entity.ApiAddresses[apiKey], ApiAddress{
|
||||
Url: instance.Url,
|
||||
Version: instance.Version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/openziti/ziti/common/cert"
|
||||
"github.com/openziti/ziti/controller/config"
|
||||
"github.com/openziti/ziti/controller/db"
|
||||
"github.com/openziti/ziti/controller/event"
|
||||
"github.com/openziti/ziti/controller/jwtsigner"
|
||||
"github.com/openziti/ziti/controller/network"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
@@ -67,6 +68,8 @@ type HostController interface {
|
||||
Identity() identity.Identity
|
||||
GetPeerSigners() []*x509.Certificate
|
||||
GetRaftIndex() uint64
|
||||
GetRaftInfo() (string, string, string)
|
||||
GetApiAddresses() (map[string][]event.ApiAddress, []byte)
|
||||
}
|
||||
|
||||
type Schemas interface {
|
||||
|
||||
@@ -50,6 +50,14 @@ type testHostController struct {
|
||||
ctx *TestContext
|
||||
}
|
||||
|
||||
func (self *testHostController) GetApiAddresses() (map[string][]event.ApiAddress, []byte) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *testHostController) GetRaftInfo() (string, string, string) {
|
||||
return "testaddr", "testid", "testversion"
|
||||
}
|
||||
|
||||
func (self *testHostController) GetRaftIndex() uint64 {
|
||||
return 0
|
||||
}
|
||||
@@ -171,7 +179,7 @@ func (ctx *TestContext) GetApiServerCsrSigner() cert.Signer {
|
||||
}
|
||||
|
||||
func (ctx *TestContext) GetControlClientCsrSigner() cert.Signer {
|
||||
panic("implement me")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *TestContext) GetHostController() HostController {
|
||||
|
||||
@@ -18,6 +18,7 @@ package mesh
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/openziti/foundation/v2/concurrenz"
|
||||
"github.com/openziti/foundation/v2/versions"
|
||||
@@ -41,9 +42,10 @@ import (
|
||||
const (
|
||||
PeerAddrHeader = 11
|
||||
|
||||
RaftConnectType = 2048
|
||||
RaftDataType = 2049
|
||||
SigningCertHeader = 2050
|
||||
RaftConnectType = 2048
|
||||
RaftDataType = 2049
|
||||
SigningCertHeader = 2050
|
||||
ApiAddressesHeader = 2051
|
||||
|
||||
ChannelTypeMesh = "ctrl.mesh"
|
||||
)
|
||||
@@ -56,6 +58,7 @@ type Peer struct {
|
||||
RaftConn *raftPeerConn
|
||||
Version *versions.VersionInfo
|
||||
SigningCerts []*x509.Certificate
|
||||
ApiAddresses map[string][]event.ApiAddress
|
||||
}
|
||||
|
||||
func (self *Peer) HandleClose(channel.Channel) {
|
||||
@@ -143,7 +146,7 @@ type Mesh interface {
|
||||
Init(bindHandler channel.BindHandler)
|
||||
}
|
||||
|
||||
func New(env Env, raftAddr raft.ServerAddress) Mesh {
|
||||
func New(env Env, raftAddr raft.ServerAddress, helloHeaderProviders []HeaderProvider) Mesh {
|
||||
versionEncoded, err := env.GetVersionProvider().EncoderDecoder().Encode(env.GetVersionProvider().AsVersionInfo())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -156,12 +159,13 @@ func New(env Env, raftAddr raft.ServerAddress) Mesh {
|
||||
network: "mesh",
|
||||
addr: string(raftAddr),
|
||||
},
|
||||
Peers: map[string]*Peer{},
|
||||
closeNotify: make(chan struct{}),
|
||||
raftAccepts: make(chan net.Conn),
|
||||
version: env.GetVersionProvider(),
|
||||
versionEncoded: versionEncoded,
|
||||
eventDispatcher: env.GetEventDispatcher(),
|
||||
Peers: map[string]*Peer{},
|
||||
closeNotify: make(chan struct{}),
|
||||
raftAccepts: make(chan net.Conn),
|
||||
version: env.GetVersionProvider(),
|
||||
versionEncoded: versionEncoded,
|
||||
eventDispatcher: env.GetEventDispatcher(),
|
||||
helloHeaderProviders: helloHeaderProviders,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +184,7 @@ type impl struct {
|
||||
readonly atomic.Bool
|
||||
clusterStateHandlers concurrenz.CopyOnWriteSlice[func(state ClusterState)]
|
||||
eventDispatcher event.Dispatcher
|
||||
helloHeaderProviders []HeaderProvider
|
||||
}
|
||||
|
||||
func (self *impl) RegisterClusterStateHandler(f func(state ClusterState)) {
|
||||
@@ -257,6 +262,10 @@ func (self *impl) GetOrConnectPeer(address string, timeout time.Duration) (*Peer
|
||||
SigningCertHeader: serverCert,
|
||||
}
|
||||
|
||||
for _, headerProvider := range self.helloHeaderProviders {
|
||||
headerProvider.Apply(headers)
|
||||
}
|
||||
|
||||
dialer := channel.NewClassicDialer(self.id, addr, headers)
|
||||
dialOptions := channel.DefaultOptions()
|
||||
dialOptions.ConnectOptions.ConnectTimeout = timeout
|
||||
@@ -293,6 +302,13 @@ func (self *impl) GetOrConnectPeer(address string, timeout time.Duration) (*Peer
|
||||
return errors.Wrap(err, "can't decode version from returned from peer")
|
||||
}
|
||||
|
||||
if apiAddressBytes, found := peer.Channel.Underlay().Headers()[ApiAddressesHeader]; found {
|
||||
err := json.Unmarshal(apiAddressBytes, &peer.ApiAddresses)
|
||||
if err != nil {
|
||||
pfxlog.Logger().WithError(err).Error("could not unmarshal api address header")
|
||||
}
|
||||
}
|
||||
|
||||
peer.Version = versionInfo
|
||||
peer.RaftConn = newRaftPeerConn(peer, self.netAddr)
|
||||
peer.SigningCerts = []*x509.Certificate{underlay.Certificates()[0]}
|
||||
@@ -331,6 +347,10 @@ func (self *impl) GetPeerInfo(address string, timeout time.Duration) (raft.Serve
|
||||
PeerAddrHeader: []byte(self.raftAddr),
|
||||
}
|
||||
|
||||
for _, headerProvider := range self.helloHeaderProviders {
|
||||
headerProvider.Apply(headers)
|
||||
}
|
||||
|
||||
dialer := channel.NewClassicDialer(self.id, addr, headers)
|
||||
dialOptions := channel.DefaultOptions()
|
||||
dialOptions.ConnectOptions.ConnectTimeout = timeout
|
||||
@@ -404,10 +424,11 @@ func (self *impl) PeerConnected(peer *Peer) error {
|
||||
|
||||
evt := event.NewClusterEvent(event.ClusterPeerConnected)
|
||||
evt.Peers = append(evt.Peers, &event.ClusterPeer{
|
||||
Id: string(peer.Id),
|
||||
Addr: peer.Address,
|
||||
Version: peer.Version.Version,
|
||||
ServerCert: peer.SigningCerts,
|
||||
Id: string(peer.Id),
|
||||
Addr: peer.Address,
|
||||
Version: peer.Version.Version,
|
||||
ServerCert: peer.SigningCerts,
|
||||
ApiAddresses: peer.ApiAddresses,
|
||||
})
|
||||
|
||||
self.eventDispatcher.AcceptClusterEvent(evt)
|
||||
@@ -522,6 +543,13 @@ func (self *impl) AcceptUnderlay(underlay channel.Underlay) error {
|
||||
}
|
||||
}
|
||||
|
||||
apiAddressesHeader, found := ch.Underlay().Headers()[ApiAddressesHeader]
|
||||
if found {
|
||||
if err := json.Unmarshal(apiAddressesHeader, &peer.ApiAddresses); err != nil {
|
||||
pfxlog.Logger().WithError(err).Error("could not parse peer api addresses header")
|
||||
}
|
||||
}
|
||||
|
||||
peer.Version = versionInfo
|
||||
|
||||
peer.RaftConn = newRaftPeerConn(peer, self.netAddr)
|
||||
@@ -560,3 +588,13 @@ func (self *impl) GetPeers() map[string]*Peer {
|
||||
func (self *impl) IsReadOnly() bool {
|
||||
return self.readonly.Load()
|
||||
}
|
||||
|
||||
type HeaderProvider interface {
|
||||
Apply(map[int32][]byte)
|
||||
}
|
||||
|
||||
type HeaderProviderFunc func(map[int32][]byte)
|
||||
|
||||
func (self HeaderProviderFunc) Apply(headers map[int32][]byte) {
|
||||
self(headers)
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ type Env interface {
|
||||
GetMetricsRegistry() metrics.Registry
|
||||
GetEventDispatcher() event.Dispatcher
|
||||
GetCloseNotify() <-chan struct{}
|
||||
GetHelloHeaderProviders() []mesh.HeaderProvider
|
||||
}
|
||||
|
||||
func NewController(env Env, migrationMgr MigrationManager) *Controller {
|
||||
@@ -540,7 +541,9 @@ func (self *Controller) Init() error {
|
||||
return err
|
||||
}
|
||||
|
||||
self.Mesh = mesh.New(self.env, localAddr)
|
||||
helloHeaderProviders := self.env.GetHelloHeaderProviders()
|
||||
|
||||
self.Mesh = mesh.New(self.env, localAddr, helloHeaderProviders)
|
||||
self.Mesh.RegisterClusterStateHandler(func(state mesh.ClusterState) {
|
||||
obs := raft.Observation{
|
||||
Raft: self.Raft,
|
||||
|
||||
@@ -113,6 +113,7 @@ type InstantStrategy struct {
|
||||
serviceHandler *constraintToIndexedEvents[*db.EdgeService]
|
||||
caHandler *constraintToIndexedEvents[*db.Ca]
|
||||
revocationHandler *constraintToIndexedEvents[*db.Revocation]
|
||||
controllerHandler *constraintToIndexedEvents[*db.Controller]
|
||||
}
|
||||
|
||||
func (strategy *InstantStrategy) AddPublicKey(cert *tls.Certificate) {
|
||||
@@ -202,6 +203,12 @@ func (strategy *InstantStrategy) Initialize(logSize uint64, bufferSize uint) err
|
||||
}
|
||||
strategy.ae.GetStores().Revocation.AddEntityConstraint(strategy.revocationHandler)
|
||||
|
||||
strategy.controllerHandler = &constraintToIndexedEvents[*db.Controller]{
|
||||
indexProvider: strategy.indexProvider,
|
||||
createHandler: strategy.ControllerCreate,
|
||||
updateHandler: strategy.ControllerUpdate,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -829,14 +836,22 @@ func (strategy *InstantStrategy) BuildServicePolicies(tx *bbolt.Tx) error {
|
||||
}
|
||||
|
||||
func (strategy *InstantStrategy) BuildPublicKeys(tx *bbolt.Tx) error {
|
||||
for _, x509Cert := range strategy.ae.HostController.GetPeerSigners() {
|
||||
publicKey := newPublicKey(x509Cert.Raw, edge_ctrl_pb.DataState_PublicKey_X509CertDer, []edge_ctrl_pb.DataState_PublicKey_Usage{edge_ctrl_pb.DataState_PublicKey_ClientX509CertValidation, edge_ctrl_pb.DataState_PublicKey_JWTValidation})
|
||||
newModel := &edge_ctrl_pb.DataState_Event_PublicKey{PublicKey: publicKey}
|
||||
for cursor := strategy.ae.GetStores().Controller.IterateIds(tx, ast.BoolNodeTrue); cursor.IsValid(); cursor.Next() {
|
||||
currentBytes := cursor.Current()
|
||||
currentId := string(currentBytes)
|
||||
|
||||
storeModel, err := strategy.ae.GetStores().Controller.LoadById(tx, currentId)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
certs := nfPem.PemStringToCertificates(storeModel.CertPem)
|
||||
|
||||
newModel := &edge_ctrl_pb.DataState_Event_PublicKey{PublicKey: newPublicKey(certs[0].Raw, edge_ctrl_pb.DataState_PublicKey_X509CertDer, []edge_ctrl_pb.DataState_PublicKey_Usage{edge_ctrl_pb.DataState_PublicKey_JWTValidation, edge_ctrl_pb.DataState_PublicKey_ClientX509CertValidation})}
|
||||
newEvent := &edge_ctrl_pb.DataState_Event{
|
||||
Action: edge_ctrl_pb.DataState_Create,
|
||||
Model: newModel,
|
||||
}
|
||||
|
||||
strategy.HandlePublicKeyEvent(newEvent, newModel)
|
||||
}
|
||||
|
||||
@@ -1244,24 +1259,16 @@ func (strategy *InstantStrategy) PostureCheckDelete(index uint64, postureCheck *
|
||||
strategy.handlePostureCheck(index, edge_ctrl_pb.DataState_Delete, postureCheck)
|
||||
}
|
||||
|
||||
func (strategy *InstantStrategy) PeerAdded(peer *db.Controller) {
|
||||
if len(peer.CertPem) > 0 {
|
||||
certs := nfPem.PemBytesToCertificates([]byte(peer.CertPem))
|
||||
func (strategy *InstantStrategy) ControllerCreate(index uint64, controller *db.Controller) {
|
||||
certs := nfPem.PemStringToCertificates(controller.CertPem)
|
||||
cert := certs[0]
|
||||
strategy.handlePublicKey(index, edge_ctrl_pb.DataState_Create, newPublicKey(cert.Raw, edge_ctrl_pb.DataState_PublicKey_X509CertDer, []edge_ctrl_pb.DataState_PublicKey_Usage{edge_ctrl_pb.DataState_PublicKey_ClientX509CertValidation, edge_ctrl_pb.DataState_PublicKey_JWTValidation}))
|
||||
}
|
||||
|
||||
if len(certs) > 0 {
|
||||
strategy.Apply(&edge_ctrl_pb.DataState_Event{
|
||||
IsSynthetic: true,
|
||||
Action: edge_ctrl_pb.DataState_Create,
|
||||
Model: &edge_ctrl_pb.DataState_Event_PublicKey{
|
||||
PublicKey: newPublicKey(certs[0].Raw, edge_ctrl_pb.DataState_PublicKey_X509CertDer, []edge_ctrl_pb.DataState_PublicKey_Usage{edge_ctrl_pb.DataState_PublicKey_ClientX509CertValidation, edge_ctrl_pb.DataState_PublicKey_JWTValidation}),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
pfxlog.Logger().Warn("peer added event, certificate pem did not parse to at least one certificate")
|
||||
}
|
||||
} else {
|
||||
pfxlog.Logger().Warn("peer added event without certificate pem")
|
||||
}
|
||||
func (strategy *InstantStrategy) ControllerUpdate(index uint64, controller *db.Controller) {
|
||||
certs := nfPem.PemStringToCertificates(controller.CertPem)
|
||||
cert := certs[0]
|
||||
strategy.handlePublicKey(index, edge_ctrl_pb.DataState_Create, newPublicKey(cert.Raw, edge_ctrl_pb.DataState_PublicKey_X509CertDer, []edge_ctrl_pb.DataState_PublicKey_Usage{edge_ctrl_pb.DataState_PublicKey_ClientX509CertValidation, edge_ctrl_pb.DataState_PublicKey_JWTValidation}))
|
||||
}
|
||||
|
||||
func (strategy *InstantStrategy) CaCreate(index uint64, ca *db.Ca) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
er1.*
|
||||
er1/
|
||||
er2.*
|
||||
er2/
|
||||
endpoints
|
||||
@@ -51,3 +51,8 @@ web:
|
||||
- binding: edge-management
|
||||
- binding: edge-client
|
||||
- binding: edge-oidc
|
||||
options:
|
||||
redirectURIs:
|
||||
- "http://localhost:*/auth/callback"
|
||||
- "http://127.0.0.1:*/auth/callback"
|
||||
- "https://oauth.pstmn.io/v1/callback"
|
||||
@@ -40,3 +40,8 @@ web:
|
||||
- binding: edge-management
|
||||
- binding: edge-client
|
||||
- binding: edge-oidc
|
||||
options:
|
||||
redirectURIs:
|
||||
- "http://localhost:*/auth/callback"
|
||||
- "http://127.0.0.1:*/auth/callback"
|
||||
- "https://oauth.pstmn.io/v1/callback"
|
||||
@@ -40,3 +40,8 @@ web:
|
||||
- binding: edge-management
|
||||
- binding: edge-client
|
||||
- binding: edge-oidc
|
||||
options:
|
||||
redirectURIs:
|
||||
- "http://localhost:*/auth/callback"
|
||||
- "http://127.0.0.1:*/auth/callback"
|
||||
- "https://oauth.pstmn.io/v1/callback"
|
||||
@@ -8,7 +8,7 @@ require (
|
||||
github.com/Jeffail/gabs/v2 v2.7.0
|
||||
github.com/MakeNowJust/heredoc v1.0.0
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/cenkalti/backoff/v4 v4.2.1
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/coreos/go-iptables v0.7.0
|
||||
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3
|
||||
github.com/dineshappavoo/basex v0.0.0-20170425072625-481a6f6dc663
|
||||
@@ -49,14 +49,14 @@ require (
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/openziti/agent v1.0.16
|
||||
github.com/openziti/channel/v2 v2.0.122
|
||||
github.com/openziti/edge-api v0.26.13
|
||||
github.com/openziti/edge-api v0.26.14
|
||||
github.com/openziti/foundation/v2 v2.0.40
|
||||
github.com/openziti/identity v1.0.73
|
||||
github.com/openziti/jwks v1.0.3
|
||||
github.com/openziti/metrics v1.2.48
|
||||
github.com/openziti/runzmd v1.0.41
|
||||
github.com/openziti/sdk-golang v0.23.14
|
||||
github.com/openziti/secretstream v0.1.17
|
||||
github.com/openziti/sdk-golang v0.23.15
|
||||
github.com/openziti/secretstream v0.1.18
|
||||
github.com/openziti/storage v0.2.33
|
||||
github.com/openziti/transport/v2 v2.0.125
|
||||
github.com/openziti/x509-claims v1.0.3
|
||||
@@ -67,7 +67,7 @@ require (
|
||||
github.com/rabbitmq/amqp091-go v1.8.1
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
|
||||
github.com/russross/blackfriday v1.6.0
|
||||
github.com/shirou/gopsutil/v3 v3.24.2
|
||||
github.com/shirou/gopsutil/v3 v3.24.3
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/spf13/cobra v1.8.0
|
||||
@@ -82,7 +82,7 @@ require (
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/sys v0.18.0
|
||||
golang.org/x/sys v0.19.0
|
||||
golang.org/x/text v0.14.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.7
|
||||
@@ -184,10 +184,9 @@ require (
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/oauth2 v0.18.0 // indirect
|
||||
golang.org/x/oauth2 v0.19.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/tools v0.18.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
nhooyr.io/websocket v1.8.10 // indirect
|
||||
|
||||
@@ -107,8 +107,8 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI=
|
||||
github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -570,8 +570,8 @@ github.com/openziti/channel/v2 v2.0.122 h1:MPALuLUuTsW2QJzaoRkrP/wGqhIeWtSsrnxt2
|
||||
github.com/openziti/channel/v2 v2.0.122/go.mod h1:n4r/pWTFYJy98hEtf4ATYVHU70OePjoM8JJzrIvXvZg=
|
||||
github.com/openziti/dilithium v0.3.3 h1:PLgQ6PMNLSTzCFbX/h98cmudgz/cU6TmjdSv5NAPD8k=
|
||||
github.com/openziti/dilithium v0.3.3/go.mod h1:vsCjI2AU/hon9e+dLhUFbCNGesJDj2ASgkySOcpmvjo=
|
||||
github.com/openziti/edge-api v0.26.13 h1:lWAHu04nk7a0AEnJBjmwijUIEE+NvNAiOcdg11dxbIY=
|
||||
github.com/openziti/edge-api v0.26.13/go.mod h1:aTRqB9J/6ISbw9+YWjzD0tvWAXY98m8yWcbiGNqAQTU=
|
||||
github.com/openziti/edge-api v0.26.14 h1:BpxKavDVdykOY7GSdKXi7klv9Im4vw7bTMujz3wFE1Q=
|
||||
github.com/openziti/edge-api v0.26.14/go.mod h1:aTRqB9J/6ISbw9+YWjzD0tvWAXY98m8yWcbiGNqAQTU=
|
||||
github.com/openziti/foundation/v2 v2.0.40 h1:8oXL77egZjnQuKuxPTHiBOh+X/I2mSJefIbnLSv8rFI=
|
||||
github.com/openziti/foundation/v2 v2.0.40/go.mod h1:38RikdtjvzDUALm3jT3PSOrU0bHCleRty6bHGdfFyUI=
|
||||
github.com/openziti/identity v1.0.73 h1:F1iF/rDQYfDIv4ktqBYwK/0C5Ra/7y92Z5Umrw4c4fk=
|
||||
@@ -582,10 +582,10 @@ github.com/openziti/metrics v1.2.48 h1:bDUcWSTWM4vXh4YU8z953Q/vtlUjtH+pSaQviKzB5
|
||||
github.com/openziti/metrics v1.2.48/go.mod h1:rLFoXigAFb5clCDqe/RlvFFjlaTr9Li7iEn3OxInmb0=
|
||||
github.com/openziti/runzmd v1.0.41 h1:Iuwe91Lzq63ux2R6+VIWEvcEKhpKkPb1QVNwrJHOuDA=
|
||||
github.com/openziti/runzmd v1.0.41/go.mod h1:T79oGLLJNnAhHzcfnlrOR39S2XGkzwYZLZh62xee0wk=
|
||||
github.com/openziti/sdk-golang v0.23.14 h1:usGFwrc7jcGkvas5TVLWQgdWs/FBUZrORb6jV+KM2eY=
|
||||
github.com/openziti/sdk-golang v0.23.14/go.mod h1:mM7C6QMcEZwVhBLwmrq8PtBMyBbXXoKr186CDpTx5rI=
|
||||
github.com/openziti/secretstream v0.1.17 h1:bcaPGGpUl0+3GzfQkshKh5slUE7QDXxFq3vyDQgHkCA=
|
||||
github.com/openziti/secretstream v0.1.17/go.mod h1:gosi8ohW+dAHhz1h/MjZEcEVWO0jisWqWjEjmx7oAEs=
|
||||
github.com/openziti/sdk-golang v0.23.15 h1:+h+zin2CB6nP8e2Sqi2Jxo4Sbo3wTp8PIfh7QNm4lPA=
|
||||
github.com/openziti/sdk-golang v0.23.15/go.mod h1:aYvN+PCUV2AHPcbgcG1Khgso5TbmNaLMke0ByshU4Hs=
|
||||
github.com/openziti/secretstream v0.1.18 h1:bMHI4ez6pVSGFzHCHHn6imkaCYqd3o9Oa8gDObf8icI=
|
||||
github.com/openziti/secretstream v0.1.18/go.mod h1:gosi8ohW+dAHhz1h/MjZEcEVWO0jisWqWjEjmx7oAEs=
|
||||
github.com/openziti/storage v0.2.33 h1:15WKxJ0J1GCNOMmOkoosjoxKN2Hrm4p3g8p9WAiMS9Y=
|
||||
github.com/openziti/storage v0.2.33/go.mod h1:AbE5KkTVlXVFHRqpc7Ug3eFpNOc1HFBFwNIYn8Rtp+s=
|
||||
github.com/openziti/transport/v2 v2.0.125 h1:6kDfabGFIE2+UPyvJVtfI43CNKcMwNOrCRX602CbDU4=
|
||||
@@ -674,8 +674,8 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y=
|
||||
github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
@@ -978,8 +978,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1075,8 +1075,9 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -1093,7 +1094,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
@@ -1202,8 +1202,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
||||
@@ -89,6 +89,7 @@ func (dialer *dialer) Dial(params xgress.DialParams) (xt.PeerData, error) {
|
||||
|
||||
log.Debug("dialing sdk client hosting service")
|
||||
dialRequest := edge.NewDialMsg(terminator.Id(), terminator.token, callerId)
|
||||
dialRequest.PutStringHeader(edge.CircuitIdHeader, params.GetCircuitId().Token)
|
||||
if pk, ok := circuitId.Data[edge.PublicKeyHeader]; ok {
|
||||
dialRequest.Headers[edge.PublicKeyHeader] = pk
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func (self *edgeClientConn) processConnect(manager state.Manager, req *channel.M
|
||||
self.listener.bindHandler.HandleXgressBind(x)
|
||||
conn.ctrlRx = x
|
||||
// send the state_connected before starting the xgress. That way we can't get a state_closed before we get state_connected
|
||||
self.sendStateConnectedReply(req, response.PeerData)
|
||||
self.sendStateConnectedReply(req, response.PeerData, response.CircuitId)
|
||||
x.Start()
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ func (self *edgeClientConn) processBindV1(manager state.Manager, req *channel.Me
|
||||
|
||||
log.Debug("registered listener for terminator")
|
||||
log.Debug("returning connection state CONNECTED to client")
|
||||
self.sendStateConnectedReply(req, nil)
|
||||
self.sendStateConnectedReply(req, nil, "")
|
||||
|
||||
log.Info("created terminator")
|
||||
}
|
||||
@@ -504,7 +504,7 @@ func (self *edgeClientConn) processBindV2(manager state.Manager, req *channel.Me
|
||||
}
|
||||
}
|
||||
|
||||
self.sendStateConnectedReply(req, nil)
|
||||
self.sendStateConnectedReply(req, nil, "")
|
||||
|
||||
if checkResult.replaceExisting {
|
||||
log.Info("sending replacement terminator success to sdk")
|
||||
@@ -683,7 +683,7 @@ func (self *edgeClientConn) processTraceRoute(msg *channel.Message, ch channel.C
|
||||
}
|
||||
}
|
||||
|
||||
func (self *edgeClientConn) sendStateConnectedReply(req *channel.Message, hostData map[uint32][]byte) {
|
||||
func (self *edgeClientConn) sendStateConnectedReply(req *channel.Message, hostData map[uint32][]byte, circuitId string) {
|
||||
connId, _ := req.GetUint32Header(edge.ConnIdHeader)
|
||||
msg := edge.NewStateConnectedMsg(connId)
|
||||
|
||||
@@ -691,6 +691,10 @@ func (self *edgeClientConn) sendStateConnectedReply(req *channel.Message, hostDa
|
||||
msg.PutBoolHeader(edge.RouterProvidedConnId, true)
|
||||
}
|
||||
|
||||
if circuitId != "" {
|
||||
msg.PutStringHeader(edge.CircuitIdHeader, circuitId)
|
||||
}
|
||||
|
||||
for k, v := range hostData {
|
||||
msg.Headers[int32(k)] = v
|
||||
}
|
||||
|
||||
@@ -343,7 +343,14 @@ func (self *Service) GetConfigOfType(configType string, target interface{}) (boo
|
||||
pfxlog.Logger().Debugf("no service config of type %v defined for service %v", configType, self.Name)
|
||||
return false, nil
|
||||
}
|
||||
if err := mapstructure.Decode(configMap, target); err != nil {
|
||||
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
|
||||
Result: target,
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("unable construct decoder (%w)", err)
|
||||
}
|
||||
if err := decoder.Decode(configMap); err != nil {
|
||||
pfxlog.Logger().WithError(err).Debugf("unable to decode service configuration for of type %v defined for service %v", configType, self.Name)
|
||||
return true, fmt.Errorf("unable to decode service config structure: %w", err)
|
||||
}
|
||||
|
||||
@@ -245,7 +245,11 @@ func (self *echoServer) accept(connType string, listener net.Listener) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Infof("%v: connection received: %v", connType, conn)
|
||||
circuitId := ""
|
||||
if edgeConn, ok := conn.(edge.Conn); ok {
|
||||
circuitId = edgeConn.GetCircuitId()
|
||||
}
|
||||
log.WithField("circuitId", circuitId).Infof("%v: connection received: %v", connType, conn)
|
||||
go self.echo(connType, conn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,10 +94,14 @@ func (self *zcatAction) run(_ *cobra.Command, args []string) {
|
||||
|
||||
var conn net.Conn
|
||||
var err error
|
||||
var circuitId string
|
||||
|
||||
log.Debugf("dialing %v:%v", network, addr)
|
||||
if network == "tcp" || network == "udp" {
|
||||
conn, err = net.Dial(network, addr)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("unable to dial %v:%v", network, addr)
|
||||
}
|
||||
} else if network == "ziti" {
|
||||
zitiConfig, cfgErr := ziti.NewConfigFromFile(self.configFile)
|
||||
if cfgErr != nil {
|
||||
@@ -121,15 +125,15 @@ func (self *zcatAction) run(_ *cobra.Command, args []string) {
|
||||
Identity: dialIdentifier,
|
||||
}
|
||||
conn, err = zitiContext.DialWithOptions(addr, dialOptions)
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("unable to dial %v:%v", network, addr)
|
||||
}
|
||||
circuitId = conn.(edge.Conn).GetCircuitId()
|
||||
} else {
|
||||
log.Fatalf("invalid network '%v'. valid values are ['ziti', 'tcp', 'udp']", network)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).Fatalf("unable to dial %v:%v", network, addr)
|
||||
}
|
||||
|
||||
log.Debugf("connected to %v:%v", network, addr)
|
||||
log.WithField("circuitId", circuitId).Debugf("connected to %v:%v", network, addr)
|
||||
|
||||
go self.copy(conn, os.Stdin)
|
||||
self.copy(os.Stdout, conn)
|
||||
|
||||
+7
-8
@@ -14,11 +14,11 @@ require (
|
||||
github.com/michaelquigley/pfxlog v0.6.10
|
||||
github.com/openziti/agent v1.0.16
|
||||
github.com/openziti/channel/v2 v2.0.122
|
||||
github.com/openziti/edge-api v0.26.13
|
||||
github.com/openziti/edge-api v0.26.14
|
||||
github.com/openziti/fablab v0.5.42
|
||||
github.com/openziti/foundation/v2 v2.0.40
|
||||
github.com/openziti/identity v1.0.73
|
||||
github.com/openziti/sdk-golang v0.23.14
|
||||
github.com/openziti/sdk-golang v0.23.15
|
||||
github.com/openziti/storage v0.2.33
|
||||
github.com/openziti/transport/v2 v2.0.125
|
||||
github.com/openziti/ziti v0.28.3
|
||||
@@ -49,7 +49,7 @@ require (
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/boltdb/bolt v1.3.1 // indirect
|
||||
github.com/c-bata/go-prompt v0.2.6 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/coreos/go-iptables v0.7.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3 // indirect
|
||||
@@ -139,7 +139,7 @@ require (
|
||||
github.com/openziti/jwks v1.0.3 // indirect
|
||||
github.com/openziti/metrics v1.2.48 // indirect
|
||||
github.com/openziti/runzmd v1.0.41 // indirect
|
||||
github.com/openziti/secretstream v0.1.17 // indirect
|
||||
github.com/openziti/secretstream v0.1.18 // indirect
|
||||
github.com/openziti/x509-claims v1.0.3 // indirect
|
||||
github.com/openziti/xweb/v2 v2.1.0 // indirect
|
||||
github.com/openziti/ziti-db-explorer v1.1.3 // indirect
|
||||
@@ -157,7 +157,7 @@ require (
|
||||
github.com/russross/blackfriday v1.6.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.2 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
@@ -189,13 +189,12 @@ require (
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/oauth2 v0.18.0 // indirect
|
||||
golang.org/x/oauth2 v0.19.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.18.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.8.7 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/resty.v1 v1.12.0 // indirect
|
||||
|
||||
+14
-16
@@ -113,8 +113,8 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI=
|
||||
github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -592,8 +592,8 @@ github.com/openziti/channel/v2 v2.0.122 h1:MPALuLUuTsW2QJzaoRkrP/wGqhIeWtSsrnxt2
|
||||
github.com/openziti/channel/v2 v2.0.122/go.mod h1:n4r/pWTFYJy98hEtf4ATYVHU70OePjoM8JJzrIvXvZg=
|
||||
github.com/openziti/dilithium v0.3.3 h1:PLgQ6PMNLSTzCFbX/h98cmudgz/cU6TmjdSv5NAPD8k=
|
||||
github.com/openziti/dilithium v0.3.3/go.mod h1:vsCjI2AU/hon9e+dLhUFbCNGesJDj2ASgkySOcpmvjo=
|
||||
github.com/openziti/edge-api v0.26.13 h1:lWAHu04nk7a0AEnJBjmwijUIEE+NvNAiOcdg11dxbIY=
|
||||
github.com/openziti/edge-api v0.26.13/go.mod h1:aTRqB9J/6ISbw9+YWjzD0tvWAXY98m8yWcbiGNqAQTU=
|
||||
github.com/openziti/edge-api v0.26.14 h1:BpxKavDVdykOY7GSdKXi7klv9Im4vw7bTMujz3wFE1Q=
|
||||
github.com/openziti/edge-api v0.26.14/go.mod h1:aTRqB9J/6ISbw9+YWjzD0tvWAXY98m8yWcbiGNqAQTU=
|
||||
github.com/openziti/fablab v0.5.42 h1:vENJKfEba2T4sSLwlKDL/IzBYfY8iHnhc4umf6IESiY=
|
||||
github.com/openziti/fablab v0.5.42/go.mod h1:HDT06y1QX8kO8ZQrgHvZmJsvc8iRybESGtlDLDII4ks=
|
||||
github.com/openziti/foundation/v2 v2.0.40 h1:8oXL77egZjnQuKuxPTHiBOh+X/I2mSJefIbnLSv8rFI=
|
||||
@@ -606,10 +606,10 @@ github.com/openziti/metrics v1.2.48 h1:bDUcWSTWM4vXh4YU8z953Q/vtlUjtH+pSaQviKzB5
|
||||
github.com/openziti/metrics v1.2.48/go.mod h1:rLFoXigAFb5clCDqe/RlvFFjlaTr9Li7iEn3OxInmb0=
|
||||
github.com/openziti/runzmd v1.0.41 h1:Iuwe91Lzq63ux2R6+VIWEvcEKhpKkPb1QVNwrJHOuDA=
|
||||
github.com/openziti/runzmd v1.0.41/go.mod h1:T79oGLLJNnAhHzcfnlrOR39S2XGkzwYZLZh62xee0wk=
|
||||
github.com/openziti/sdk-golang v0.23.14 h1:usGFwrc7jcGkvas5TVLWQgdWs/FBUZrORb6jV+KM2eY=
|
||||
github.com/openziti/sdk-golang v0.23.14/go.mod h1:mM7C6QMcEZwVhBLwmrq8PtBMyBbXXoKr186CDpTx5rI=
|
||||
github.com/openziti/secretstream v0.1.17 h1:bcaPGGpUl0+3GzfQkshKh5slUE7QDXxFq3vyDQgHkCA=
|
||||
github.com/openziti/secretstream v0.1.17/go.mod h1:gosi8ohW+dAHhz1h/MjZEcEVWO0jisWqWjEjmx7oAEs=
|
||||
github.com/openziti/sdk-golang v0.23.15 h1:+h+zin2CB6nP8e2Sqi2Jxo4Sbo3wTp8PIfh7QNm4lPA=
|
||||
github.com/openziti/sdk-golang v0.23.15/go.mod h1:aYvN+PCUV2AHPcbgcG1Khgso5TbmNaLMke0ByshU4Hs=
|
||||
github.com/openziti/secretstream v0.1.18 h1:bMHI4ez6pVSGFzHCHHn6imkaCYqd3o9Oa8gDObf8icI=
|
||||
github.com/openziti/secretstream v0.1.18/go.mod h1:gosi8ohW+dAHhz1h/MjZEcEVWO0jisWqWjEjmx7oAEs=
|
||||
github.com/openziti/storage v0.2.33 h1:15WKxJ0J1GCNOMmOkoosjoxKN2Hrm4p3g8p9WAiMS9Y=
|
||||
github.com/openziti/storage v0.2.33/go.mod h1:AbE5KkTVlXVFHRqpc7Ug3eFpNOc1HFBFwNIYn8Rtp+s=
|
||||
github.com/openziti/transport/v2 v2.0.125 h1:6kDfabGFIE2+UPyvJVtfI43CNKcMwNOrCRX602CbDU4=
|
||||
@@ -700,8 +700,8 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y=
|
||||
github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
|
||||
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
@@ -1005,8 +1005,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1102,8 +1102,9 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -1120,7 +1121,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
@@ -1229,8 +1229,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
||||
Reference in New Issue
Block a user