Skip to content

Commit

Permalink
fixes #2591 ziti edge login will not fail with split APIs
Browse files Browse the repository at this point in the history
- ziti edge login now properly probes endpoints and their return content
  type along with the existing status code check
- probed endpoint responses are no longer blindly parsed
- the management endpoint is the default initial probe point, falling
  back to the client version endpoint then the legacy root version
  endpoint
- the SPA/ZAC bindings for web apis has been moved to the webapis folder
- improved erroring and messaging for the SPA/ZAC handling
  • Loading branch information
andrewpmartinez committed Dec 13, 2024
1 parent 1932a6d commit 5e0237e
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 163 deletions.
3 changes: 1 addition & 2 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import (
"github.com/openziti/ziti/controller/xt_smartrouting"
"github.com/openziti/ziti/controller/xt_sticky"
"github.com/openziti/ziti/controller/xt_weighted"
"github.com/openziti/ziti/controller/zac"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"math/big"
Expand Down Expand Up @@ -309,7 +308,7 @@ func (c *Controller) initWeb() {
logrus.WithError(err).Fatalf("failed to create metrics api factory")
}

if err = c.xweb.GetRegistry().Add(zac.NewZitiAdminConsoleFactory()); err != nil {
if err = c.xweb.GetRegistry().Add(webapis.NewZitiAdminConsoleFactory()); err != nil {
logrus.WithError(err).Fatalf("failed to create single page application factory")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
*/

package spa_handler
package webapis

import (
"net/http"
Expand All @@ -23,28 +23,29 @@ import (
"strings"
)

type SinglePageAppHandler struct {
type GenericHttpHandler struct {
HttpHandler http.Handler
BindingKey string
ContextRoot string
}

func (spa *SinglePageAppHandler) Binding() string {
func (spa *GenericHttpHandler) Binding() string {
return spa.BindingKey
}

func (spa *SinglePageAppHandler) Options() map[interface{}]interface{} {
func (spa *GenericHttpHandler) Options() map[interface{}]interface{} {
return nil
}

func (spa *SinglePageAppHandler) RootPath() string {
func (spa *GenericHttpHandler) RootPath() string {
return "/" + spa.BindingKey
}

func (spa *SinglePageAppHandler) IsHandler(r *http.Request) bool {
return strings.HasPrefix(r.URL.Path, spa.RootPath()) || strings.HasPrefix(r.URL.Path, "/assets")
func (spa *GenericHttpHandler) IsHandler(r *http.Request) bool {
return strings.HasPrefix(r.URL.Path, spa.ContextRoot) || strings.HasPrefix(r.URL.Path, "/assets")
}

func (spa *SinglePageAppHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
func (spa *GenericHttpHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
spa.HttpHandler.ServeHTTP(writer, request)
}

Expand Down
69 changes: 69 additions & 0 deletions controller/webapis/zac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package webapis

import (
"fmt"
"github.com/openziti/xweb/v2"
log "github.com/sirupsen/logrus"
"strings"
)

const (
Binding = "zac"
)

type ZitiAdminConsoleFactory struct {
}

var _ xweb.ApiHandlerFactory = &ZitiAdminConsoleFactory{}

func NewZitiAdminConsoleFactory() *ZitiAdminConsoleFactory {
return &ZitiAdminConsoleFactory{}
}

func (factory *ZitiAdminConsoleFactory) Validate(*xweb.InstanceConfig) error {
return nil
}

func (factory *ZitiAdminConsoleFactory) Binding() string {
return Binding
}

func (factory *ZitiAdminConsoleFactory) New(_ *xweb.ServerConfig, options map[interface{}]interface{}) (xweb.ApiHandler, error) {
locVal := options["location"]
if locVal == nil || locVal == "" {
return nil, fmt.Errorf("location must be supplied in the %s options", Binding)
}

loc, ok := locVal.(string)

if !ok {
return nil, fmt.Errorf("location must be a string for the %s options", Binding)
}

indexFileVal := options["indexFile"]
indexFile := "index.html"

if indexFileVal != nil {
newFileVal, ok := indexFileVal.(string)

if !ok {
return nil, fmt.Errorf("indexFile must be a string for the %s options", Binding)
}

newFileVal = strings.TrimSpace(newFileVal)

if newFileVal != "" {
indexFile = newFileVal
}
}

contextRoot := "/" + Binding
spa := &GenericHttpHandler{
HttpHandler: SpaHandler(loc, contextRoot, indexFile),
BindingKey: Binding,
ContextRoot: contextRoot,
}

log.Infof("initializing ZAC SPA Handler from %s", locVal)
return spa, nil
}
46 changes: 0 additions & 46 deletions controller/zac/factory.go

This file was deleted.

185 changes: 103 additions & 82 deletions etc/ctrl.with.edge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ ctrl:
# connections. The value of newListener must be resolvable both via DNS and validate via certificates
#newListener: tls:localhost:6262

events:
jsonLogger:
subscriptions:
- type: connect
- type: sdk
#events:
# jsonLogger:
# subscriptions:
# - type: connect
# - type: sdk
# - type: entityChange
# include:
# - services
Expand All @@ -105,10 +105,10 @@ events:
# - type: services
# - type: edge.entityCounts
# interval: 5s
handler:
type: file
format: json
path: /tmp/ziti-events.log
# handler:
# type: file
# format: json
# path: /tmp/ziti-events.log
# usageLogger:
# subscriptions:
# - type: fabric.usage
Expand Down Expand Up @@ -164,7 +164,7 @@ edge:
# address - required
# The default address (host:port) to use for enrollment for the Client API. This value must match one of the addresses
# defined in a bind point's address field for the `edge-client` API in the web section.
address: 127.0.0.1:1280
address: 127.0.0.1:443
# enrollment - required
# A section containing settings pertaining to enrollment.
enrollment:
Expand Down Expand Up @@ -197,82 +197,103 @@ edge:
web:
# name - required
# Provides a name for this listener, used for logging output. Not required to be unique, but is highly suggested.
- name: all-apis-localhost
# bindPoints - required
# One or more bind points are required. A bind point specifies an interface (interface:port string) that defines
# where on the host machine the webListener will listen and the address (host:port) that should be used to
# publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for
# incoming address resolution as well as used in responses in the API.
- name: client1
bindPoints:
#interface - required
# A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces
- interface: 127.0.0.1:1280

# address - required
# The public address that external incoming requests will be able to resolve. Used in request processing and
# response content that requires full host:port/path addresses.
address: 127.0.0.1:1280

# newAddress - optional
# A host:port string which will be sent out as an HTTP header "ziti-new-address" if specified. If the header
# is present, clients should update location configuration to immediately use the new address for future
# connections. The value of newAddress must be resolvable both via DNS and validate via certificates
newAddress: localhost:1280
# identity - optional
# Allows the webListener to have a specific identity instead of defaulting to the root `identity` section.
# identity:
# cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-client.cert.pem
# server_cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-server.cert.pem
# key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/ctrl.key.pem
# ca: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ca-chain.cert.pem
# options - optional
# Allows the specification of webListener level options - mainly dealing with HTTP/TLS settings. These options are
# used for all http servers started by the current webListener.
options:
# idleTimeout - optional, default 5000ms
# The maximum amount of idle time in milliseconds allowed for pipelined HTTP requests. Setting this too high
# can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value
# will cause clients to reconnect on subsequent HTTPs requests.
idleTimeout: 5000ms #http timeouts, new

# readTimeout - optional, default 5000ms
# The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher
# value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency
# or packet loss. A lower value can risk losing connections to high latency/packet loss clients.

readTimeout: 5000ms
# writeTimeout - optional, default 10000ms
# The total maximum time in milliseconds that the http server will wait for a single requests to be received and
# responded too. A higher value can allow long running requests to consume resources on the host. A lower value
# can risk ending requests before the server has a chance to respond.

writeTimeout: 100000ms
# minTLSVersion - optional, default TSL1.2
# The minimum version of TSL to support

minTLSVersion: TLS1.2
# maxTLSVersion - optional, default TSL1.3
# The maximum version of TSL to support

maxTLSVersion: TLS1.3
# apis - required
# Allows one or more APIs to be bound to this webListener
- interface: 0.0.0.0:443
address: 127.0.0.1:443
apis:
# binding - required
# Specifies an API to bind to this webListener. Built-in APIs are
# - health-checks
# - edge-management
# - edge-client
# - fabric-management
- binding: health-checks
- binding: fabric
- binding: edge-management
- binding: edge-client
- binding: edge-oidc
options: {}
- name: all-the-rest
bindPoints:
- interface: 0.0.0.0:8443
address: 127.0.0.1:8443
apis:
- binding: edge-management
options: { }
- binding: fabric
options: { }
- binding: zac
options:
redirectURIs:
- "http://localhost:*/auth/callback"
- "http://127.0.0.1:*/auth/callback"
location: C:\Users\andre\repos\openziti\gross
indexFile: index.html
#
# - name: all-apis-localhost
# # bindPoints - required
# # One or more bind points are required. A bind point specifies an interface (interface:port string) that defines
# # where on the host machine the webListener will listen and the address (host:port) that should be used to
# # publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for
# # incoming address resolution as well as used in responses in the API.
# bindPoints:
# #interface - required
# # A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces
# - interface: 127.0.0.1:1280
#
# # address - required
# # The public address that external incoming requests will be able to resolve. Used in request processing and
# # response content that requires full host:port/path addresses.
# address: 127.0.0.1:1280
#
# # newAddress - optional
# # A host:port string which will be sent out as an HTTP header "ziti-new-address" if specified. If the header
# # is present, clients should update location configuration to immediately use the new address for future
# # connections. The value of newAddress must be resolvable both via DNS and validate via certificates
# newAddress: localhost:1280
# # identity - optional
# # Allows the webListener to have a specific identity instead of defaulting to the root `identity` section.
# # identity:
# # cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-client.cert.pem
# # server_cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-server.cert.pem
# # key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/ctrl.key.pem
# # ca: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ca-chain.cert.pem
# # options - optional
# # Allows the specification of webListener level options - mainly dealing with HTTP/TLS settings. These options are
# # used for all http servers started by the current webListener.
# options:
# # idleTimeout - optional, default 5000ms
# # The maximum amount of idle time in milliseconds allowed for pipelined HTTP requests. Setting this too high
# # can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value
# # will cause clients to reconnect on subsequent HTTPs requests.
# idleTimeout: 5000ms #http timeouts, new
#
# # readTimeout - optional, default 5000ms
# # The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher
# # value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency
# # or packet loss. A lower value can risk losing connections to high latency/packet loss clients.
#
# readTimeout: 5000ms
# # writeTimeout - optional, default 10000ms
# # The total maximum time in milliseconds that the http server will wait for a single requests to be received and
# # responded too. A higher value can allow long running requests to consume resources on the host. A lower value
# # can risk ending requests before the server has a chance to respond.
#
# writeTimeout: 100000ms
# # minTLSVersion - optional, default TSL1.2
# # The minimum version of TSL to support
#
# minTLSVersion: TLS1.2
# # maxTLSVersion - optional, default TSL1.3
# # The maximum version of TSL to support
#
# maxTLSVersion: TLS1.3
# # apis - required
# # Allows one or more APIs to be bound to this webListener
# apis:
# # binding - required
# # Specifies an API to bind to this webListener. Built-in APIs are
# # - health-checks
# # - edge-management
# # - edge-client
# # - fabric-management
# - binding: health-checks
# - binding: fabric
# - binding: edge-management
# - binding: edge-client
# - binding: edge-oidc
# options:
# redirectURIs:
# - "http://localhost:*/auth/callback"
# - "http://127.0.0.1:*/auth/callback"

commandRateLimiter:
enabled: true
Expand Down
Loading

0 comments on commit 5e0237e

Please sign in to comment.