Merge pull request #1548 from openziti/filter-circuits-links

Support filter/sort/page on circuits and links. Fixes #1547
This commit is contained in:
Paul Lorenz
2023-12-06 16:13:49 -05:00
committed by GitHub
29 changed files with 1164 additions and 393 deletions
+14 -4
View File
@@ -4,6 +4,7 @@
* SDK Hosting Improvements
* Terminator validation utility
* Circuit/Link query support
## SDK Hosting Improvments
@@ -21,6 +22,12 @@ setup logic is correct. However it may also be used to diagnose and resolve issu
ziti fabric validate terminators
```
## Circuit/Link Query Support
Previously listing circuit and links always showed the full list. This is because these types are in memory only and are not stored
in the bbolt datastore. There's now basic support for querying in-memory types and circuits and links can now be filtered/paged/sorted
the same as other entity types.
## Component Updates and Bug Fixes
* github.com/openziti/channel/v2: [v2.0.105 -> v2.0.110](https://github.com/openziti/channel/compare/v2.0.105...v2.0.110)
@@ -28,13 +35,16 @@ ziti fabric validate terminators
* github.com/openziti/foundation/v2: [v2.0.33 -> v2.0.35](https://github.com/openziti/foundation/compare/v2.0.33...v2.0.35)
* github.com/openziti/identity: [v1.0.66 -> v1.0.68](https://github.com/openziti/identity/compare/v1.0.66...v1.0.68)
* github.com/openziti/metrics: [v1.2.37 -> v1.2.40](https://github.com/openziti/metrics/compare/v1.2.37...v1.2.40)
* github.com/openziti/sdk-golang: [v0.20.129 -> v0.20.139](https://github.com/openziti/sdk-golang/compare/v0.20.129...v0.20.139)
* [Issue #457](https://github.com/openziti/sdk-golang/issues/457) - Add inspect support
* [Issue #450](https://github.com/openziti/sdk-golang/issues/450) - Support idempotent terminator creation
* github.com/openziti/runzmd: [v1.0.33 -> v1.0.36](https://github.com/openziti/runzmd/compare/v1.0.33...v1.0.36)
* github.com/openziti/sdk-golang: [v0.20.129 -> v0.21.1](https://github.com/openziti/sdk-golang/compare/v0.20.129...v0.21.1)
* github.com/openziti/secretstream: [v0.1.13 -> v0.1.14](https://github.com/openziti/secretstream/compare/v0.1.13...v0.1.14)
* github.com/openziti/storage: [v0.2.23 -> v0.2.26](https://github.com/openziti/storage/compare/v0.2.23...v0.2.26)
* [Issue #57](https://github.com/openziti/storage/issues/57) - Support querying collections of in memory objects
* github.com/openziti/transport/v2: [v2.0.113 -> v2.0.119](https://github.com/openziti/transport/compare/v2.0.113...v2.0.119)
* github.com/openziti/dilithium: [v0.3.3 -> v0.3.5](https://github.com/openziti/dilithium/compare/v0.3.3...v0.3.5)
* github.com/openziti/ziti: [v0.31.0 -> v0.31.1](https://github.com/openziti/ziti/compare/v0.31.0...v0.31.1)
* [Issue #1547](https://github.com/openziti/ziti/issues/1547) - Support filtering, sorting and paging circuits and links
* [Issue #1446](https://github.com/openziti/ziti/issues/1446) - Allow for idempotent sdk based terminators
* [Issue #1523](https://github.com/openziti/ziti/issues/1523) - Bootstrap members not working
* [Issue #1525](https://github.com/openziti/ziti/issues/1525) - Improve cluster list output
+2 -5
View File
@@ -17,7 +17,6 @@
package api_impl
import (
"github.com/go-openapi/strfmt"
"github.com/openziti/ziti/controller/api"
"github.com/openziti/ziti/controller/network"
@@ -46,7 +45,7 @@ func (factory *CircuitLinkFactoryIml) Links(entity LinkEntity) rest_model.Links
}
func MapCircuitToRestModel(_ *network.Network, _ api.RequestContext, circuit *network.Circuit) (*rest_model.CircuitDetail, error) {
path := &rest_model.CircuitDetailPath{}
path := &rest_model.Path{}
for _, node := range circuit.Path.Nodes {
path.Nodes = append(path.Nodes, ToEntityRef(node.Name, node, RouterLinkFactory))
}
@@ -54,14 +53,12 @@ func MapCircuitToRestModel(_ *network.Network, _ api.RequestContext, circuit *ne
path.Links = append(path.Links, ToEntityRef(link.Id, link, LinkLinkFactory))
}
createdAt := strfmt.DateTime(circuit.CreatedAt)
ret := &rest_model.CircuitDetail{
ID: &circuit.Id,
BaseEntity: BaseEntityToRestModel(circuit, CircuitLinkFactory),
ClientID: circuit.ClientId,
Path: path,
Service: ToEntityRef(circuit.Service.Name, circuit.Service, ServiceLinkFactory),
Terminator: ToEntityRef(circuit.Terminator.GetId(), circuit.Terminator, TerminatorLinkFactory),
CreatedAt: &createdAt,
}
return ret, nil
+14 -9
View File
@@ -18,14 +18,13 @@ package api_impl
import (
"github.com/go-openapi/runtime/middleware"
"github.com/openziti/storage/boltz"
"github.com/openziti/ziti/controller/api"
"github.com/openziti/ziti/controller/change"
"github.com/openziti/ziti/controller/network"
"github.com/openziti/ziti/controller/rest_model"
"github.com/openziti/ziti/controller/rest_server/operations"
"github.com/openziti/ziti/controller/rest_server/operations/circuit"
"github.com/openziti/storage/boltz"
"sort"
)
func init() {
@@ -59,10 +58,16 @@ func (r *CircuitRouter) Register(fabricApi *operations.ZitiFabricAPI, wrapper Re
func (r *CircuitRouter) ListCircuits(n *network.Network, rc api.RequestContext) {
ListWithEnvelopeFactory(rc, defaultToListEnvelope, func(rc api.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) {
circuits := n.GetAllCircuits()
sort.Slice(circuits, func(i, j int) bool {
return circuits[i].Id < circuits[j].Id
})
query, err := queryOptions.getFullQuery(n.GetCircuitStore())
if err != nil {
return nil, err
}
circuits, count, err := n.GetCircuitStore().QueryEntitiesC(query)
if err != nil {
return nil, err
}
apiCircuits := make([]*rest_model.CircuitDetail, 0, len(circuits))
for _, modelCircuit := range circuits {
apiCircuit, err := MapCircuitToRestModel(n, rc, modelCircuit)
@@ -73,9 +78,9 @@ func (r *CircuitRouter) ListCircuits(n *network.Network, rc api.RequestContext)
}
result := &QueryResult{
Result: apiCircuits,
Count: int64(len(circuits)),
Limit: -1,
Offset: 0,
Count: count,
Limit: *query.GetLimit(),
Offset: *query.GetSkip(),
FilterableFields: nil,
}
return result, nil
+14 -9
View File
@@ -18,6 +18,7 @@ package api_impl
import (
"github.com/go-openapi/runtime/middleware"
"github.com/openziti/storage/boltz"
"github.com/openziti/ziti/controller/api"
"github.com/openziti/ziti/controller/change"
"github.com/openziti/ziti/controller/fields"
@@ -25,8 +26,6 @@ import (
"github.com/openziti/ziti/controller/rest_model"
"github.com/openziti/ziti/controller/rest_server/operations"
"github.com/openziti/ziti/controller/rest_server/operations/link"
"github.com/openziti/storage/boltz"
"sort"
)
func init() {
@@ -64,10 +63,16 @@ func (r *LinkRouter) Register(fabricApi *operations.ZitiFabricAPI, wrapper Reque
func (r *LinkRouter) ListLinks(n *network.Network, rc api.RequestContext) {
ListWithEnvelopeFactory(rc, defaultToListEnvelope, func(rc api.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) {
links := n.GetAllLinks()
sort.Slice(links, func(i, j int) bool {
return links[i].Id < links[j].Id
})
query, err := queryOptions.getFullQuery(n.GetLinkStore())
if err != nil {
return nil, err
}
links, count, err := n.GetLinkStore().QueryEntitiesC(query)
if err != nil {
return nil, err
}
apiLinks := make([]*rest_model.LinkDetail, 0, len(links))
for _, modelLink := range links {
apiLink, err := MapLinkToRestModel(n, rc, modelLink)
@@ -78,9 +83,9 @@ func (r *LinkRouter) ListLinks(n *network.Network, rc api.RequestContext) {
}
result := &QueryResult{
Result: apiLinks,
Count: int64(len(links)),
Limit: -1,
Offset: 0,
Count: count,
Limit: *query.GetLimit(),
Offset: *query.GetSkip(),
FilterableFields: nil,
}
return result, nil
+12 -7
View File
@@ -43,18 +43,21 @@ func (qo *PublicQueryOptions) String() string {
return fmt.Sprintf("[QueryOption Predicate: '%v', Sort: '%v', Paging: '%v']", qo.Predicate, qo.Sort, qo.Paging)
}
func (qo *PublicQueryOptions) getFullQuery(store boltz.Store) (ast.Query, error) {
func (qo *PublicQueryOptions) getFullQuery(symbolTypes ast.SymbolTypes) (ast.Query, error) {
if qo.Predicate == "" {
qo.Predicate = "true"
}
query, err := ast.Parse(store, qo.Predicate)
query, err := ast.Parse(symbolTypes, qo.Predicate)
if err != nil {
return nil, errorz.NewInvalidFilter(err)
}
if err = boltz.ValidateSymbolsArePublic(query, store); err != nil {
return nil, errorz.NewInvalidFilter(err)
store, isStore := symbolTypes.(boltz.Store)
if isStore {
if err = boltz.ValidateSymbolsArePublic(query, store); err != nil {
return nil, errorz.NewInvalidFilter(err)
}
}
pfxlog.Logger().Debugf("query: %v", qo)
@@ -78,13 +81,15 @@ func (qo *PublicQueryOptions) getFullQuery(store boltz.Store) (ast.Query, error)
if len(sortFields) == 0 && qo.Sort != "" {
sortQueryString := "true sort by " + qo.Sort
sortQuery, err := ast.Parse(store, sortQueryString)
sortQuery, err := ast.Parse(symbolTypes, sortQueryString)
if err != nil {
return nil, errorz.NewInvalidSort(err)
}
if err = boltz.ValidateSymbolsArePublic(sortQuery, store); err != nil {
return nil, errorz.NewInvalidSort(err)
if isStore {
if err = boltz.ValidateSymbolsArePublic(sortQuery, store); err != nil {
return nil, errorz.NewInvalidSort(err)
}
}
if err = query.AdoptSortFields(sortQuery); err != nil {
+57 -3
View File
@@ -17,10 +17,11 @@
package network
import (
"github.com/openziti/identity"
"github.com/openziti/storage/objectz"
"github.com/openziti/ziti/common/logcontext"
"github.com/openziti/ziti/controller/idgen"
"github.com/openziti/ziti/controller/xt"
"github.com/openziti/ziti/common/logcontext"
"github.com/openziti/identity"
"github.com/orcaman/concurrent-map/v2"
"sync/atomic"
"time"
@@ -36,6 +37,35 @@ type Circuit struct {
Rerouting atomic.Bool
PeerData xt.PeerData
CreatedAt time.Time
UpdatedAt time.Time
}
func (self *Circuit) GetId() string {
return self.Id
}
func (self *Circuit) SetId(string) {
// id cannot be updated
}
func (self *Circuit) GetCreatedAt() time.Time {
return self.CreatedAt
}
func (self *Circuit) GetUpdatedAt() time.Time {
return self.UpdatedAt
}
func (self *Circuit) GetTags() map[string]interface{} {
result := map[string]interface{}{}
for k, v := range self.Tags {
result[k] = v
}
return result
}
func (self *Circuit) IsSystemEntity() bool {
return false
}
func (self *Circuit) cost(minRouterCost uint16) int64 {
@@ -57,13 +87,37 @@ func (self *Circuit) HasRouter(routerId string) bool {
type circuitController struct {
circuits cmap.ConcurrentMap[string, *Circuit]
idGenerator idgen.Generator
store *objectz.ObjectStore[*Circuit]
}
func newCircuitController() *circuitController {
return &circuitController{
result := &circuitController{
circuits: cmap.New[*Circuit](),
idGenerator: idgen.NewGenerator(),
}
result.store = objectz.NewObjectStore[*Circuit](func() objectz.ObjectIterator[*Circuit] {
return IterateCMap(result.circuits)
})
result.store.AddStringSymbol("id", func(entity *Circuit) *string {
return &entity.Id
})
result.store.AddStringSymbol("clientId", func(entity *Circuit) *string {
return &entity.ClientId
})
result.store.AddStringSymbol("service", func(entity *Circuit) *string {
return &entity.Service.Id
})
result.store.AddStringSymbol("terminator", func(entity *Circuit) *string {
val := entity.Terminator.GetId()
return &val
})
result.store.AddDatetimeSymbol("createdAt", func(entity *Circuit) *time.Time {
return &entity.CreatedAt
})
result.store.AddDatetimeSymbol("updatedAt", func(entity *Circuit) *time.Time {
return &entity.CreatedAt
})
return result
}
func (self *circuitController) nextCircuitId() (string, error) {
+54
View File
@@ -0,0 +1,54 @@
/*
Copyright NetFoundry Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package network
import (
"github.com/openziti/storage/objectz"
cmap "github.com/orcaman/concurrent-map/v2"
)
func IterateCMap[T any](m cmap.ConcurrentMap[string, T]) objectz.ObjectIterator[T] {
iterator := &tupleChannelIterator[T]{
c: m.IterBuffered(),
valid: true,
}
iterator.Next()
return iterator
}
type tupleChannelIterator[T any] struct {
c <-chan cmap.Tuple[string, T]
current T
valid bool
}
func (self *tupleChannelIterator[T]) IsValid() bool {
return self.valid
}
func (self *tupleChannelIterator[T]) Next() {
next, ok := <-self.c
if !ok {
self.valid = false
} else {
self.current = next.Val
}
}
func (self *tupleChannelIterator[T]) Current() T {
return self.current
}
+50 -2
View File
@@ -17,9 +17,10 @@
package network
import (
"github.com/openziti/foundation/v2/info"
"github.com/openziti/storage/objectz"
"github.com/openziti/ziti/common/pb/ctrl_pb"
"github.com/openziti/ziti/controller/idgen"
"github.com/openziti/foundation/v2/info"
"github.com/orcaman/concurrent-map/v2"
"math"
"sync"
@@ -31,6 +32,7 @@ type linkController struct {
idGenerator idgen.Generator
lock sync.Mutex
initialLatency time.Duration
store *objectz.ObjectStore[*Link]
}
func newLinkController(options *Options) *linkController {
@@ -38,11 +40,57 @@ func newLinkController(options *Options) *linkController {
if options != nil {
initialLatency = options.InitialLinkLatency
}
return &linkController{
result := &linkController{
linkTable: newLinkTable(),
idGenerator: idgen.NewGenerator(),
initialLatency: initialLatency,
}
result.store = objectz.NewObjectStore[*Link](func() objectz.ObjectIterator[*Link] {
return IterateCMap[*Link](result.linkTable.links)
})
result.store.AddStringSymbol("id", func(entity *Link) *string {
return &entity.Id
})
result.store.AddStringSymbol("protocol", func(entity *Link) *string {
return &entity.Protocol
})
result.store.AddStringSymbol("dialAddress", func(entity *Link) *string {
return &entity.DialAddress
})
result.store.AddStringSymbol("sourceRouter", func(entity *Link) *string {
return &entity.Src.Id
})
result.store.AddStringSymbol("destRouter", func(entity *Link) *string {
return &entity.Dst.Id
})
result.store.AddInt64Symbol("cost", func(entity *Link) *int64 {
val := entity.GetCost()
return &val
})
result.store.AddInt64Symbol("staticCost", func(entity *Link) *int64 {
val := int64(entity.GetStaticCost())
return &val
})
result.store.AddInt64Symbol("destLatency", func(entity *Link) *int64 {
val := entity.GetDstLatency()
return &val
})
result.store.AddInt64Symbol("sourceLatency", func(entity *Link) *int64 {
val := entity.GetSrcLatency()
return &val
})
result.store.AddStringSymbol("state", func(entity *Link) *string {
if state := entity.CurrentState(); state != nil {
val := state.Mode.String()
return &val
}
return nil
})
return result
}
func (linkController *linkController) add(link *Link) {
+5 -5
View File
@@ -18,6 +18,11 @@ package network
import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/foundation/v2/goroutines"
"github.com/openziti/foundation/v2/versions"
"github.com/openziti/storage/ast"
"github.com/openziti/storage/boltz"
"github.com/openziti/ziti/common/pb/cmd_pb"
"github.com/openziti/ziti/controller/change"
"github.com/openziti/ziti/controller/command"
"github.com/openziti/ziti/controller/db"
@@ -25,11 +30,6 @@ import (
"github.com/openziti/ziti/controller/idgen"
"github.com/openziti/ziti/controller/ioc"
"github.com/openziti/ziti/controller/models"
"github.com/openziti/ziti/common/pb/cmd_pb"
"github.com/openziti/foundation/v2/goroutines"
"github.com/openziti/foundation/v2/versions"
"github.com/openziti/storage/ast"
"github.com/openziti/storage/boltz"
"go.etcd.io/bbolt"
)
+14 -1
View File
@@ -22,6 +22,7 @@ import (
"encoding/json"
"fmt"
"github.com/openziti/foundation/v2/goroutines"
"github.com/openziti/storage/objectz"
fabricMetrics "github.com/openziti/ziti/common/metrics"
"github.com/openziti/ziti/controller/event"
"os"
@@ -271,6 +272,14 @@ func (network *Network) GetAllCircuits() []*Circuit {
return network.circuitController.all()
}
func (network *Network) GetCircuitStore() *objectz.ObjectStore[*Circuit] {
return network.circuitController.store
}
func (network *Network) GetLinkStore() *objectz.ObjectStore[*Link] {
return network.linkController.store
}
func (network *Network) RouteResult(rs *RouteStatus) bool {
return network.routeSenderController.forwardRouteResult(rs)
}
@@ -599,6 +608,7 @@ func (network *Network) CreateCircuit(params CreateCircuitParams) (*Circuit, err
delete(peerData, uint32(ctrl_msg.TerminatorLocalAddressHeader))
delete(peerData, uint32(ctrl_msg.TerminatorRemoteAddressHeader))
now := time.Now()
// 6: Create Circuit Object
circuit := &Circuit{
Id: circuitId,
@@ -607,7 +617,8 @@ func (network *Network) CreateCircuit(params CreateCircuitParams) (*Circuit, err
Path: path,
Terminator: terminator,
PeerData: peerData,
CreatedAt: time.Now(),
CreatedAt: now,
UpdatedAt: now,
Tags: tags,
}
network.circuitController.add(circuit)
@@ -1031,6 +1042,7 @@ func (network *Network) rerouteCircuit(circuit *Circuit, deadline time.Time) err
if cq, err := network.UpdatePath(circuit.Path); err == nil {
circuit.Path = cq
circuit.UpdatedAt = time.Now()
rms := cq.CreateRouteMessages(SmartRerouteAttempt, circuit.Id, circuit.Terminator, deadline)
@@ -1060,6 +1072,7 @@ func (network *Network) smartReroute(circuit *Circuit, cq *Path, deadline time.T
defer circuit.Rerouting.Store(false)
circuit.Path = cq
circuit.UpdatedAt = time.Now()
rms := cq.CreateRouteMessages(SmartRerouteAttempt, circuit.Id, circuit.Terminator, deadline)
@@ -18,10 +18,10 @@ package persistence
import (
"fmt"
"github.com/openziti/storage/boltztest"
"github.com/openziti/ziti/common/eid"
"github.com/openziti/ziti/controller/change"
"github.com/openziti/ziti/controller/db"
"github.com/openziti/storage/boltztest"
"testing"
"time"
@@ -71,7 +71,7 @@ func (ctx *TestContext) testServiceParentChild(_ *testing.T) {
//
//err = ctx.GetDb().View(func(tx *bbolt.Tx) error {
// query := fmt.Sprintf(`id = "%v" and name = "%v"`, fabricService.Id, edgeService.Name)
// ids, _, err := ctx.stores.EdgeService.QueryIds(tx, query)
// ids, _, err := ctx.stores.EdgeService.QueryEntities(tx, query)
// if err != nil {
// return err
// }
@@ -38,6 +38,7 @@ import (
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewListCircuitsParams creates a new ListCircuitsParams object,
@@ -82,6 +83,16 @@ func NewListCircuitsParamsWithHTTPClient(client *http.Client) *ListCircuitsParam
Typically these are written to a http.Request.
*/
type ListCircuitsParams struct {
// Filter.
Filter *string
// Limit.
Limit *int64
// Offset.
Offset *int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
@@ -135,6 +146,39 @@ func (o *ListCircuitsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithFilter adds the filter to the list circuits params
func (o *ListCircuitsParams) WithFilter(filter *string) *ListCircuitsParams {
o.SetFilter(filter)
return o
}
// SetFilter adds the filter to the list circuits params
func (o *ListCircuitsParams) SetFilter(filter *string) {
o.Filter = filter
}
// WithLimit adds the limit to the list circuits params
func (o *ListCircuitsParams) WithLimit(limit *int64) *ListCircuitsParams {
o.SetLimit(limit)
return o
}
// SetLimit adds the limit to the list circuits params
func (o *ListCircuitsParams) SetLimit(limit *int64) {
o.Limit = limit
}
// WithOffset adds the offset to the list circuits params
func (o *ListCircuitsParams) WithOffset(offset *int64) *ListCircuitsParams {
o.SetOffset(offset)
return o
}
// SetOffset adds the offset to the list circuits params
func (o *ListCircuitsParams) SetOffset(offset *int64) {
o.Offset = offset
}
// WriteToRequest writes these params to a swagger request
func (o *ListCircuitsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
@@ -143,6 +187,57 @@ func (o *ListCircuitsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.
}
var res []error
if o.Filter != nil {
// query param filter
var qrFilter string
if o.Filter != nil {
qrFilter = *o.Filter
}
qFilter := qrFilter
if qFilter != "" {
if err := r.SetQueryParam("filter", qFilter); err != nil {
return err
}
}
}
if o.Limit != nil {
// query param limit
var qrLimit int64
if o.Limit != nil {
qrLimit = *o.Limit
}
qLimit := swag.FormatInt64(qrLimit)
if qLimit != "" {
if err := r.SetQueryParam("limit", qLimit); err != nil {
return err
}
}
}
if o.Offset != nil {
// query param offset
var qrOffset int64
if o.Offset != nil {
qrOffset = *o.Offset
}
qOffset := swag.FormatInt64(qrOffset)
if qOffset != "" {
if err := r.SetQueryParam("offset", qOffset); err != nil {
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
@@ -38,6 +38,7 @@ import (
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewListLinksParams creates a new ListLinksParams object,
@@ -82,6 +83,16 @@ func NewListLinksParamsWithHTTPClient(client *http.Client) *ListLinksParams {
Typically these are written to a http.Request.
*/
type ListLinksParams struct {
// Filter.
Filter *string
// Limit.
Limit *int64
// Offset.
Offset *int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
@@ -135,6 +146,39 @@ func (o *ListLinksParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithFilter adds the filter to the list links params
func (o *ListLinksParams) WithFilter(filter *string) *ListLinksParams {
o.SetFilter(filter)
return o
}
// SetFilter adds the filter to the list links params
func (o *ListLinksParams) SetFilter(filter *string) {
o.Filter = filter
}
// WithLimit adds the limit to the list links params
func (o *ListLinksParams) WithLimit(limit *int64) *ListLinksParams {
o.SetLimit(limit)
return o
}
// SetLimit adds the limit to the list links params
func (o *ListLinksParams) SetLimit(limit *int64) {
o.Limit = limit
}
// WithOffset adds the offset to the list links params
func (o *ListLinksParams) WithOffset(offset *int64) *ListLinksParams {
o.SetOffset(offset)
return o
}
// SetOffset adds the offset to the list links params
func (o *ListLinksParams) SetOffset(offset *int64) {
o.Offset = offset
}
// WriteToRequest writes these params to a swagger request
func (o *ListLinksParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
@@ -143,6 +187,57 @@ func (o *ListLinksParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Reg
}
var res []error
if o.Filter != nil {
// query param filter
var qrFilter string
if o.Filter != nil {
qrFilter = *o.Filter
}
qFilter := qrFilter
if qFilter != "" {
if err := r.SetQueryParam("filter", qFilter); err != nil {
return err
}
}
}
if o.Limit != nil {
// query param limit
var qrLimit int64
if o.Limit != nil {
qrLimit = *o.Limit
}
qLimit := swag.FormatInt64(qrLimit)
if qLimit != "" {
if err := r.SetQueryParam("limit", qLimit); err != nil {
return err
}
}
}
if o.Offset != nil {
// query param offset
var qrOffset int64
if o.Offset != nil {
qrOffset = *o.Offset
}
qOffset := swag.FormatInt64(qrOffset)
if qOffset != "" {
if err := r.SetQueryParam("offset", qOffset); err != nil {
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
+78 -196
View File
@@ -31,7 +31,6 @@ package rest_model
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
@@ -43,22 +42,14 @@ import (
//
// swagger:model circuitDetail
type CircuitDetail struct {
BaseEntity
// client Id
ClientID string `json:"clientId,omitempty"`
// created at
// Required: true
// Format: date-time
CreatedAt *strfmt.DateTime `json:"createdAt"`
// id
// Required: true
ID *string `json:"id"`
// path
// Required: true
Path *CircuitDetailPath `json:"path"`
Path *Path `json:"path"`
// service
// Required: true
@@ -69,15 +60,81 @@ type CircuitDetail struct {
Terminator *EntityRef `json:"terminator"`
}
// UnmarshalJSON unmarshals this object from a JSON structure
func (m *CircuitDetail) UnmarshalJSON(raw []byte) error {
// AO0
var aO0 BaseEntity
if err := swag.ReadJSON(raw, &aO0); err != nil {
return err
}
m.BaseEntity = aO0
// AO1
var dataAO1 struct {
ClientID string `json:"clientId,omitempty"`
Path *Path `json:"path"`
Service *EntityRef `json:"service"`
Terminator *EntityRef `json:"terminator"`
}
if err := swag.ReadJSON(raw, &dataAO1); err != nil {
return err
}
m.ClientID = dataAO1.ClientID
m.Path = dataAO1.Path
m.Service = dataAO1.Service
m.Terminator = dataAO1.Terminator
return nil
}
// MarshalJSON marshals this object to a JSON structure
func (m CircuitDetail) MarshalJSON() ([]byte, error) {
_parts := make([][]byte, 0, 2)
aO0, err := swag.WriteJSON(m.BaseEntity)
if err != nil {
return nil, err
}
_parts = append(_parts, aO0)
var dataAO1 struct {
ClientID string `json:"clientId,omitempty"`
Path *Path `json:"path"`
Service *EntityRef `json:"service"`
Terminator *EntityRef `json:"terminator"`
}
dataAO1.ClientID = m.ClientID
dataAO1.Path = m.Path
dataAO1.Service = m.Service
dataAO1.Terminator = m.Terminator
jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1)
if errAO1 != nil {
return nil, errAO1
}
_parts = append(_parts, jsonDataAO1)
return swag.ConcatJSON(_parts...), nil
}
// Validate validates this circuit detail
func (m *CircuitDetail) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateCreatedAt(formats); err != nil {
res = append(res, err)
}
if err := m.validateID(formats); err != nil {
// validation for a type composition with BaseEntity
if err := m.BaseEntity.Validate(formats); err != nil {
res = append(res, err)
}
@@ -99,28 +156,6 @@ func (m *CircuitDetail) Validate(formats strfmt.Registry) error {
return nil
}
func (m *CircuitDetail) validateCreatedAt(formats strfmt.Registry) error {
if err := validate.Required("createdAt", "body", m.CreatedAt); err != nil {
return err
}
if err := validate.FormatOf("createdAt", "body", "date-time", m.CreatedAt.String(), formats); err != nil {
return err
}
return nil
}
func (m *CircuitDetail) validateID(formats strfmt.Registry) error {
if err := validate.Required("id", "body", m.ID); err != nil {
return err
}
return nil
}
func (m *CircuitDetail) validatePath(formats strfmt.Registry) error {
if err := validate.Required("path", "body", m.Path); err != nil {
@@ -185,6 +220,11 @@ func (m *CircuitDetail) validateTerminator(formats strfmt.Registry) error {
func (m *CircuitDetail) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
// validation for a type composition with BaseEntity
if err := m.BaseEntity.ContextValidate(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidatePath(ctx, formats); err != nil {
res = append(res, err)
}
@@ -268,161 +308,3 @@ func (m *CircuitDetail) UnmarshalBinary(b []byte) error {
*m = res
return nil
}
// CircuitDetailPath circuit detail path
//
// swagger:model CircuitDetailPath
type CircuitDetailPath struct {
// links
Links []*EntityRef `json:"links"`
// nodes
Nodes []*EntityRef `json:"nodes"`
}
// Validate validates this circuit detail path
func (m *CircuitDetailPath) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateLinks(formats); err != nil {
res = append(res, err)
}
if err := m.validateNodes(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CircuitDetailPath) validateLinks(formats strfmt.Registry) error {
if swag.IsZero(m.Links) { // not required
return nil
}
for i := 0; i < len(m.Links); i++ {
if swag.IsZero(m.Links[i]) { // not required
continue
}
if m.Links[i] != nil {
if err := m.Links[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("path" + "." + "links" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("path" + "." + "links" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *CircuitDetailPath) validateNodes(formats strfmt.Registry) error {
if swag.IsZero(m.Nodes) { // not required
return nil
}
for i := 0; i < len(m.Nodes); i++ {
if swag.IsZero(m.Nodes[i]) { // not required
continue
}
if m.Nodes[i] != nil {
if err := m.Nodes[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("path" + "." + "nodes" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("path" + "." + "nodes" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this circuit detail path based on the context it is used
func (m *CircuitDetailPath) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateLinks(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateNodes(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CircuitDetailPath) contextValidateLinks(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Links); i++ {
if m.Links[i] != nil {
if err := m.Links[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("path" + "." + "links" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("path" + "." + "links" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *CircuitDetailPath) contextValidateNodes(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Nodes); i++ {
if m.Nodes[i] != nil {
if err := m.Nodes[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("path" + "." + "nodes" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("path" + "." + "nodes" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *CircuitDetailPath) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *CircuitDetailPath) UnmarshalBinary(b []byte) error {
var res CircuitDetailPath
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
+197
View File
@@ -0,0 +1,197 @@
// Code generated by go-swagger; DO NOT EDIT.
//
// Copyright NetFoundry Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// __ __ _
// \ \ / / (_)
// \ \ /\ / /_ _ _ __ _ __ _ _ __ __ _
// \ \/ \/ / _` | '__| '_ \| | '_ \ / _` |
// \ /\ / (_| | | | | | | | | | | (_| | : This file is generated, do not edit it.
// \/ \/ \__,_|_| |_| |_|_|_| |_|\__, |
// __/ |
// |___/
package rest_model
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Path path
//
// swagger:model path
type Path struct {
// links
Links []*EntityRef `json:"links"`
// nodes
Nodes []*EntityRef `json:"nodes"`
}
// Validate validates this path
func (m *Path) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateLinks(formats); err != nil {
res = append(res, err)
}
if err := m.validateNodes(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Path) validateLinks(formats strfmt.Registry) error {
if swag.IsZero(m.Links) { // not required
return nil
}
for i := 0; i < len(m.Links); i++ {
if swag.IsZero(m.Links[i]) { // not required
continue
}
if m.Links[i] != nil {
if err := m.Links[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("links" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("links" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *Path) validateNodes(formats strfmt.Registry) error {
if swag.IsZero(m.Nodes) { // not required
return nil
}
for i := 0; i < len(m.Nodes); i++ {
if swag.IsZero(m.Nodes[i]) { // not required
continue
}
if m.Nodes[i] != nil {
if err := m.Nodes[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("nodes" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("nodes" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this path based on the context it is used
func (m *Path) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateLinks(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateNodes(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Path) contextValidateLinks(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Links); i++ {
if m.Links[i] != nil {
if err := m.Links[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("links" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("links" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *Path) contextValidateNodes(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Nodes); i++ {
if m.Nodes[i] != nil {
if err := m.Nodes[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("nodes" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("nodes" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *Path) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Path) UnmarshalBinary(b []byte) error {
var res Path
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
+130 -89
View File
@@ -77,6 +77,17 @@ func init() {
],
"summary": "List circuits",
"operationId": "listCircuits",
"parameters": [
{
"$ref": "#/parameters/limit"
},
{
"$ref": "#/parameters/offset"
},
{
"$ref": "#/parameters/filter"
}
],
"responses": {
"200": {
"$ref": "#/responses/listCircuits"
@@ -330,6 +341,17 @@ func init() {
],
"summary": "List links",
"operationId": "listLinks",
"parameters": [
{
"$ref": "#/parameters/limit"
},
{
"$ref": "#/parameters/offset"
},
{
"$ref": "#/parameters/filter"
}
],
"responses": {
"200": {
"$ref": "#/responses/listLinks"
@@ -1225,49 +1247,33 @@ func init() {
}
},
"circuitDetail": {
"type": "object",
"required": [
"id",
"service",
"terminator",
"path",
"createdAt"
],
"properties": {
"clientId": {
"type": "string"
"allOf": [
{
"$ref": "#/definitions/baseEntity"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"id": {
"type": "string"
},
"path": {
{
"type": "object",
"required": [
"service",
"terminator",
"path"
],
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
"clientId": {
"type": "string"
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
"path": {
"$ref": "#/definitions/path"
},
"service": {
"$ref": "#/definitions/entityRef"
},
"terminator": {
"$ref": "#/definitions/entityRef"
}
}
},
"service": {
"$ref": "#/definitions/entityRef"
},
"terminator": {
"$ref": "#/definitions/entityRef"
}
}
]
},
"circuitList": {
"type": "array",
@@ -1787,6 +1793,23 @@ func init() {
}
}
},
"path": {
"type": "object",
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
}
}
},
"raftMemberListRequest": {
"type": "object"
},
@@ -2641,6 +2664,23 @@ func init() {
],
"summary": "List circuits",
"operationId": "listCircuits",
"parameters": [
{
"type": "integer",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"name": "offset",
"in": "query"
},
{
"type": "string",
"name": "filter",
"in": "query"
}
],
"responses": {
"200": {
"description": "A list of circuits",
@@ -3373,6 +3413,23 @@ func init() {
],
"summary": "List links",
"operationId": "listLinks",
"parameters": [
{
"type": "integer",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"name": "offset",
"in": "query"
},
{
"type": "string",
"name": "filter",
"in": "query"
}
],
"responses": {
"200": {
"description": "A list of links",
@@ -6203,23 +6260,6 @@ func init() {
}
},
"definitions": {
"CircuitDetailPath": {
"type": "object",
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
}
}
},
"apiError": {
"type": "object",
"properties": {
@@ -6336,49 +6376,33 @@ func init() {
}
},
"circuitDetail": {
"type": "object",
"required": [
"id",
"service",
"terminator",
"path",
"createdAt"
],
"properties": {
"clientId": {
"type": "string"
"allOf": [
{
"$ref": "#/definitions/baseEntity"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"id": {
"type": "string"
},
"path": {
{
"type": "object",
"required": [
"service",
"terminator",
"path"
],
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
"clientId": {
"type": "string"
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
"path": {
"$ref": "#/definitions/path"
},
"service": {
"$ref": "#/definitions/entityRef"
},
"terminator": {
"$ref": "#/definitions/entityRef"
}
}
},
"service": {
"$ref": "#/definitions/entityRef"
},
"terminator": {
"$ref": "#/definitions/entityRef"
}
}
]
},
"circuitList": {
"type": "array",
@@ -6898,6 +6922,23 @@ func init() {
}
}
},
"path": {
"type": "object",
"properties": {
"links": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/definitions/entityRef"
}
}
}
},
"raftMemberListRequest": {
"type": "object"
},
@@ -33,7 +33,10 @@ import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewListCircuitsParams creates a new ListCircuitsParams object
@@ -52,6 +55,19 @@ type ListCircuitsParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
In: query
*/
Filter *string
/*
In: query
*/
Limit *int64
/*
In: query
*/
Offset *int64
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -63,8 +79,88 @@ func (o *ListCircuitsParams) BindRequest(r *http.Request, route *middleware.Matc
o.HTTPRequest = r
qs := runtime.Values(r.URL.Query())
qFilter, qhkFilter, _ := qs.GetOK("filter")
if err := o.bindFilter(qFilter, qhkFilter, route.Formats); err != nil {
res = append(res, err)
}
qLimit, qhkLimit, _ := qs.GetOK("limit")
if err := o.bindLimit(qLimit, qhkLimit, route.Formats); err != nil {
res = append(res, err)
}
qOffset, qhkOffset, _ := qs.GetOK("offset")
if err := o.bindOffset(qOffset, qhkOffset, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindFilter binds and validates parameter Filter from query.
func (o *ListCircuitsParams) bindFilter(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
o.Filter = &raw
return nil
}
// bindLimit binds and validates parameter Limit from query.
func (o *ListCircuitsParams) bindLimit(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
value, err := swag.ConvertInt64(raw)
if err != nil {
return errors.InvalidType("limit", "query", "int64", raw)
}
o.Limit = &value
return nil
}
// bindOffset binds and validates parameter Offset from query.
func (o *ListCircuitsParams) bindOffset(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
value, err := swag.ConvertInt64(raw)
if err != nil {
return errors.InvalidType("offset", "query", "int64", raw)
}
o.Offset = &value
return nil
}
@@ -33,11 +33,19 @@ import (
"errors"
"net/url"
golangswaggerpaths "path"
"github.com/go-openapi/swag"
)
// ListCircuitsURL generates an URL for the list circuits operation
type ListCircuitsURL struct {
Filter *string
Limit *int64
Offset *int64
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
@@ -67,6 +75,34 @@ func (o *ListCircuitsURL) Build() (*url.URL, error) {
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
qs := make(url.Values)
var filterQ string
if o.Filter != nil {
filterQ = *o.Filter
}
if filterQ != "" {
qs.Set("filter", filterQ)
}
var limitQ string
if o.Limit != nil {
limitQ = swag.FormatInt64(*o.Limit)
}
if limitQ != "" {
qs.Set("limit", limitQ)
}
var offsetQ string
if o.Offset != nil {
offsetQ = swag.FormatInt64(*o.Offset)
}
if offsetQ != "" {
qs.Set("offset", offsetQ)
}
_result.RawQuery = qs.Encode()
return &_result, nil
}
@@ -33,7 +33,10 @@ import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewListLinksParams creates a new ListLinksParams object
@@ -52,6 +55,19 @@ type ListLinksParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
In: query
*/
Filter *string
/*
In: query
*/
Limit *int64
/*
In: query
*/
Offset *int64
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -63,8 +79,88 @@ func (o *ListLinksParams) BindRequest(r *http.Request, route *middleware.Matched
o.HTTPRequest = r
qs := runtime.Values(r.URL.Query())
qFilter, qhkFilter, _ := qs.GetOK("filter")
if err := o.bindFilter(qFilter, qhkFilter, route.Formats); err != nil {
res = append(res, err)
}
qLimit, qhkLimit, _ := qs.GetOK("limit")
if err := o.bindLimit(qLimit, qhkLimit, route.Formats); err != nil {
res = append(res, err)
}
qOffset, qhkOffset, _ := qs.GetOK("offset")
if err := o.bindOffset(qOffset, qhkOffset, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindFilter binds and validates parameter Filter from query.
func (o *ListLinksParams) bindFilter(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
o.Filter = &raw
return nil
}
// bindLimit binds and validates parameter Limit from query.
func (o *ListLinksParams) bindLimit(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
value, err := swag.ConvertInt64(raw)
if err != nil {
return errors.InvalidType("limit", "query", "int64", raw)
}
o.Limit = &value
return nil
}
// bindOffset binds and validates parameter Offset from query.
func (o *ListLinksParams) bindOffset(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: false
// AllowEmptyValue: false
if raw == "" { // empty values pass all other validations
return nil
}
value, err := swag.ConvertInt64(raw)
if err != nil {
return errors.InvalidType("offset", "query", "int64", raw)
}
o.Offset = &value
return nil
}
@@ -33,11 +33,19 @@ import (
"errors"
"net/url"
golangswaggerpaths "path"
"github.com/go-openapi/swag"
)
// ListLinksURL generates an URL for the list links operation
type ListLinksURL struct {
Filter *string
Limit *int64
Offset *int64
_basePath string
// avoid unkeyed usage
_ struct{}
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
@@ -67,6 +75,34 @@ func (o *ListLinksURL) Build() (*url.URL, error) {
}
_result.Path = golangswaggerpaths.Join(_basePath, _path)
qs := make(url.Values)
var filterQ string
if o.Filter != nil {
filterQ = *o.Filter
}
if filterQ != "" {
qs.Set("filter", filterQ)
}
var limitQ string
if o.Limit != nil {
limitQ = swag.FormatInt64(*o.Limit)
}
if limitQ != "" {
qs.Set("limit", limitQ)
}
var offsetQ string
if o.Offset != nil {
offsetQ = swag.FormatInt64(*o.Offset)
}
if offsetQ != "" {
qs.Set("offset", offsetQ)
}
_result.RawQuery = qs.Encode()
return &_result, nil
}
+35 -29
View File
@@ -486,6 +486,10 @@ paths:
tags:
- Link
operationId: listLinks
parameters:
- $ref: '#/parameters/limit'
- $ref: '#/parameters/offset'
- $ref: '#/parameters/filter'
responses:
'200':
$ref: '#/responses/listLinks'
@@ -565,6 +569,10 @@ paths:
tags:
- Circuit
operationId: listCircuits
parameters:
- $ref: '#/parameters/limit'
- $ref: '#/parameters/offset'
- $ref: '#/parameters/filter'
responses:
'200':
$ref: '#/responses/listCircuits'
@@ -1755,42 +1763,40 @@ definitions:
items:
$ref: '#/definitions/circuitDetail'
circuitDetail:
type: object
required:
- id
- service
- terminator
- path
- createdAt
properties:
id:
type: string
clientId:
type: string
service:
$ref: '#/definitions/entityRef'
terminator:
$ref: '#/definitions/entityRef'
createdAt:
type: string
format: date-time
path:
type: object
allOf:
- $ref: '#/definitions/baseEntity'
- type: object
required:
- service
- terminator
- path
properties:
nodes:
type: array
items:
$ref: '#/definitions/entityRef'
links:
type: array
items:
$ref: '#/definitions/entityRef'
clientId:
type: string
service:
$ref: '#/definitions/entityRef'
terminator:
$ref: '#/definitions/entityRef'
path:
$ref: '#/definitions/path'
circuitDelete:
type: object
properties:
immediate:
type: boolean
path:
type: object
properties:
nodes:
type: array
items:
$ref: '#/definitions/entityRef'
links:
type: array
items:
$ref: '#/definitions/entityRef'
###################################################################
# Inspections
##################################################################
+2 -2
View File
@@ -53,10 +53,10 @@ require (
github.com/openziti/identity v1.0.68
github.com/openziti/jwks v1.0.3
github.com/openziti/metrics v1.2.40
github.com/openziti/runzmd v1.0.33
github.com/openziti/runzmd v1.0.36
github.com/openziti/sdk-golang v0.20.139
github.com/openziti/secretstream v0.1.14
github.com/openziti/storage v0.2.23
github.com/openziti/storage v0.2.26
github.com/openziti/transport/v2 v2.0.119
github.com/openziti/x509-claims v1.0.3
github.com/openziti/xweb/v2 v2.1.0
+4 -4
View File
@@ -630,14 +630,14 @@ github.com/openziti/jwks v1.0.3 h1:hf8wkb+Cg4nH/HM0KROFd7u+C3DkRVcFZJ7tDV+4icc=
github.com/openziti/jwks v1.0.3/go.mod h1:t4xxq8vlXGsPn29kiQVnZBBDDnEoOFqtJoHibkJunQQ=
github.com/openziti/metrics v1.2.40 h1:gySRgR8prCPqaEjmUtX0eXFs7NkI9uPAzp+z6A8+JqA=
github.com/openziti/metrics v1.2.40/go.mod h1:HXdVryf3xpZfnY4VcaOjMxiBv+qw0wJlEJNLbooB9hY=
github.com/openziti/runzmd v1.0.33 h1:tOyjRoUuVXIo1z1pNU32jALWkMmhzsSaDrhLtuOn3Ts=
github.com/openziti/runzmd v1.0.33/go.mod h1:8c/uvZR/XWXQNllTq6LuTpfKL2DTNxfI2X2wYhgRwik=
github.com/openziti/runzmd v1.0.36 h1:HOqTZFzTTFu52qmCAQfFvKDmCSl8ZqP1PQQ0UnJIA4E=
github.com/openziti/runzmd v1.0.36/go.mod h1:jYqummjskmFh63htJFF2SrUuvxNQifqd5REUhYVaY/A=
github.com/openziti/sdk-golang v0.20.139 h1:1TaRTd5KmSrfHR6W3ASuj651o37h4NOXTRC6K53Pf3k=
github.com/openziti/sdk-golang v0.20.139/go.mod h1:z2gUWwonLa+haq40cfsNE2P23RoD+SZhxWulG7w7aI0=
github.com/openziti/secretstream v0.1.14 h1:Ta+nB5Prcct+L5LIKUA1nE56QhWS6lMPQYTlpxUltU0=
github.com/openziti/secretstream v0.1.14/go.mod h1:/hhuLfu+GIv0+cnapfsu/VOnXEvmTt3GKtCu+lQ0RIw=
github.com/openziti/storage v0.2.23 h1:R5ZBGDGC/LvOz3fE/GlevwbPZ3HL7VxYEvlhKuezvNU=
github.com/openziti/storage v0.2.23/go.mod h1:NZCrN2dLtRU73McVEflK5prDgYds9J54mMNz5DmgvZE=
github.com/openziti/storage v0.2.26 h1:15EbOC6A//dsdLSs/RYJP6Qn3Rj6Od4btXEWGezatxc=
github.com/openziti/storage v0.2.26/go.mod h1:pDCkPIN7h9L+FyJP+hcfOwk+GofzrrNoYsAThOjNza0=
github.com/openziti/transport/v2 v2.0.119 h1:KOgHU+9EZUVPvv8ncifqHmNEcFUHbJHigo3jyPvWnOc=
github.com/openziti/transport/v2 v2.0.119/go.mod h1:H2IIBP6ed9isE/eJHGXtAZL0d73ApYOpLG9sSvutNNI=
github.com/openziti/x509-claims v1.0.3 h1:HNdQ8Nf1agB3lBs1gahcO6zfkeS4S5xoQ2/PkY4HRX0=
@@ -1,12 +1,12 @@
# Purpose
This script sets up an echo service which is hosted by two SDK applications and
is accessed by another sdk application.
This script sets up an echo service which is hosted by two SDK applications and is accessed by
another sdk application.
# Prerequisites
You need at least one controller and an edge router running. for this to work.
You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart).
You need at least one controller and an edge router running. for this to work. You can use the
quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart).
# Setup
@@ -40,10 +40,10 @@ ziti edge create service echo -a echo
## Create and enroll the hosting identities
```action:ziti
ziti edge create identity service echo-host-1 -a echo,echo-host -o echo-host-1.jwt
ziti edge create identity echo-host-1 -a echo,echo-host -o echo-host-1.jwt
ziti edge enroll --rm echo-host-1.jwt
ziti edge create identity service echo-host-2 -a echo,echo-host -o echo-host-2.jwt
ziti edge create identity echo-host-2 -a echo,echo-host -o echo-host-2.jwt
ziti edge enroll --rm echo-host-2.jwt
```
@@ -62,8 +62,7 @@ ziti demo echo-server -i echo-host-1.json
ziti demo echo-server -i echo-host-2.json
```
and
the zcat client using
and the zcat client using
```
ziti demo zcat -i zcat.json ziti:echo
+3 -3
View File
@@ -4,8 +4,8 @@ This script sets up the SDK client side for an echo service
# Prerequisites
You need at least one controller and an edge router running. for this to work.
You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart).
You need at least one controller and an edge router running. for this to work. You can use the
quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart).
# Setup
@@ -27,7 +27,7 @@ ziti edge delete service-policies echo-dial
## Create and enroll the client app identity
```action:ziti
ziti edge create identity service zcat -a echo,echo-client -o zcat.jwt
ziti edge create identity zcat -a echo,echo-client -o zcat.jwt
ziti edge enroll --rm zcat.jwt
```
@@ -4,8 +4,8 @@ This script sets up an echo service which is hosted by an SDK application.
# Prerequisites
You need at least one controller and an edge router running. for this to work.
You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart).
You need at least one controller and an edge router running. for this to work. You can use the
quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart).
# Setup
@@ -39,7 +39,7 @@ ziti edge create service echo -a echo
## Create and enroll the hosting identity
```action:ziti
ziti edge create identity service echo-host-1 -a echo,echo-host -o echo-host-1.jwt
ziti edge create identity echo-host-1 -a echo,echo-host -o echo-host-1.jwt
ziti edge enroll --rm echo-host-1.jwt
```
@@ -57,8 +57,7 @@ You should now be to run the echo server with
ziti demo echo-server -i echo-host-1.json
```
and
the zcat client using
and the zcat client using
```
ziti demo zcat -i zcat.json ziti:echo
+6 -4
View File
@@ -18,6 +18,7 @@ package fabric
import (
"fmt"
"github.com/openziti/foundation/v2/stringz"
fabric_rest_client "github.com/openziti/ziti/controller/rest_client"
"github.com/openziti/ziti/controller/rest_client/circuit"
"github.com/openziti/ziti/controller/rest_client/link"
@@ -25,11 +26,11 @@ import (
"github.com/openziti/ziti/controller/rest_client/service"
"github.com/openziti/ziti/controller/rest_client/terminator"
"github.com/openziti/ziti/controller/rest_model"
"github.com/openziti/foundation/v2/stringz"
"github.com/openziti/ziti/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/helpers"
"strings"
"time"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
@@ -92,7 +93,7 @@ func runListCircuits(o *api.Options) error {
ctx, cancelF := o.GetContext()
defer cancelF()
result, err := client.Circuit.ListCircuits(&circuit.ListCircuitsParams{
//Filter: o.GetFilter(),
Filter: o.GetFilter(),
Context: ctx,
})
return outputResult(result, err, o, outputCircuits)
@@ -102,7 +103,7 @@ func runListCircuits(o *api.Options) error {
func outputCircuits(o *api.Options, results *circuit.ListCircuitsOK) error {
t := table.NewWriter()
t.SetStyle(table.StyleRounded)
t.AppendHeader(table.Row{"ID", "Client", "Service", "Terminator", "Path"})
t.AppendHeader(table.Row{"ID", "Client", "Service", "Terminator", "CreatedAt", "Path"})
for _, entity := range results.Payload.Data {
pathLabel := strings.Builder{}
@@ -126,6 +127,7 @@ func outputCircuits(o *api.Options, results *circuit.ListCircuitsOK) error {
entity.ClientID,
entity.Service.Name,
entity.Terminator.ID,
time.Time(*entity.CreatedAt).UTC().Format(time.DateTime),
pathLabel.String(),
})
}
@@ -140,7 +142,7 @@ func runListLinks(o *api.Options) error {
ctx, cancelF := o.GetContext()
defer cancelF()
result, err := client.Link.ListLinks(&link.ListLinksParams{
//Filter: o.GetFilter(),
Filter: o.GetFilter(),
Context: ctx,
})
return outputResult(result, err, o, outputLinks)
+2 -2
View File
@@ -16,7 +16,7 @@ require (
github.com/openziti/foundation/v2 v2.0.35
github.com/openziti/identity v1.0.68
github.com/openziti/sdk-golang v0.20.139
github.com/openziti/storage v0.2.23
github.com/openziti/storage v0.2.26
github.com/openziti/transport/v2 v2.0.119
github.com/openziti/ziti v0.28.3
github.com/pkg/errors v0.9.1
@@ -131,7 +131,7 @@ require (
github.com/openziti/edge-api v0.26.1 // indirect
github.com/openziti/jwks v1.0.3 // indirect
github.com/openziti/metrics v1.2.40 // indirect
github.com/openziti/runzmd v1.0.33 // indirect
github.com/openziti/runzmd v1.0.36 // indirect
github.com/openziti/secretstream v0.1.14 // indirect
github.com/openziti/x509-claims v1.0.3 // indirect
github.com/openziti/xweb/v2 v2.1.0 // indirect
+4 -4
View File
@@ -642,14 +642,14 @@ github.com/openziti/jwks v1.0.3 h1:hf8wkb+Cg4nH/HM0KROFd7u+C3DkRVcFZJ7tDV+4icc=
github.com/openziti/jwks v1.0.3/go.mod h1:t4xxq8vlXGsPn29kiQVnZBBDDnEoOFqtJoHibkJunQQ=
github.com/openziti/metrics v1.2.40 h1:gySRgR8prCPqaEjmUtX0eXFs7NkI9uPAzp+z6A8+JqA=
github.com/openziti/metrics v1.2.40/go.mod h1:HXdVryf3xpZfnY4VcaOjMxiBv+qw0wJlEJNLbooB9hY=
github.com/openziti/runzmd v1.0.33 h1:tOyjRoUuVXIo1z1pNU32jALWkMmhzsSaDrhLtuOn3Ts=
github.com/openziti/runzmd v1.0.33/go.mod h1:8c/uvZR/XWXQNllTq6LuTpfKL2DTNxfI2X2wYhgRwik=
github.com/openziti/runzmd v1.0.36 h1:HOqTZFzTTFu52qmCAQfFvKDmCSl8ZqP1PQQ0UnJIA4E=
github.com/openziti/runzmd v1.0.36/go.mod h1:jYqummjskmFh63htJFF2SrUuvxNQifqd5REUhYVaY/A=
github.com/openziti/sdk-golang v0.20.139 h1:1TaRTd5KmSrfHR6W3ASuj651o37h4NOXTRC6K53Pf3k=
github.com/openziti/sdk-golang v0.20.139/go.mod h1:z2gUWwonLa+haq40cfsNE2P23RoD+SZhxWulG7w7aI0=
github.com/openziti/secretstream v0.1.14 h1:Ta+nB5Prcct+L5LIKUA1nE56QhWS6lMPQYTlpxUltU0=
github.com/openziti/secretstream v0.1.14/go.mod h1:/hhuLfu+GIv0+cnapfsu/VOnXEvmTt3GKtCu+lQ0RIw=
github.com/openziti/storage v0.2.23 h1:R5ZBGDGC/LvOz3fE/GlevwbPZ3HL7VxYEvlhKuezvNU=
github.com/openziti/storage v0.2.23/go.mod h1:NZCrN2dLtRU73McVEflK5prDgYds9J54mMNz5DmgvZE=
github.com/openziti/storage v0.2.26 h1:15EbOC6A//dsdLSs/RYJP6Qn3Rj6Od4btXEWGezatxc=
github.com/openziti/storage v0.2.26/go.mod h1:pDCkPIN7h9L+FyJP+hcfOwk+GofzrrNoYsAThOjNza0=
github.com/openziti/transport/v2 v2.0.119 h1:KOgHU+9EZUVPvv8ncifqHmNEcFUHbJHigo3jyPvWnOc=
github.com/openziti/transport/v2 v2.0.119/go.mod h1:H2IIBP6ed9isE/eJHGXtAZL0d73ApYOpLG9sSvutNNI=
github.com/openziti/x509-claims v1.0.3 h1:HNdQ8Nf1agB3lBs1gahcO6zfkeS4S5xoQ2/PkY4HRX0=