package api
import (
"time"
)
// Intention defines an intention for the Connect Service Graph. This defines
// the allowed or denied behavior of a connection between two services using
// Connect.
type Intention struct {
// ID is the UUID-based ID for the intention, always generated by Consul.
ID string
// Description is a human-friendly description of this intention.
// It is opaque to Consul and is only stored and transferred in API
// requests.
Description string
// SourceNS, SourceName are the namespace and name, respectively, of
// the source service. Either of these may be the wildcard "*", but only
// the full value can be a wildcard. Partial wildcards are not allowed.
// The source may also be a non-Consul service, as specified by SourceType.
//
// DestinationNS, DestinationName is the same, but for the destination
// service. The same rules apply. The destination is always a Consul
// service.
SourceNS , SourceName string
DestinationNS , DestinationName string
// SourceType is the type of the value for the source.
SourceType IntentionSourceType
// Action is whether this is a whitelist or blacklist intention.
Action IntentionAction
// DefaultAddr, DefaultPort of the local listening proxy (if any) to
// make this connection.
DefaultAddr string
DefaultPort int
// Meta is arbitrary metadata associated with the intention. This is
// opaque to Consul but is served in API responses.
Meta map [ string ] string
// CreatedAt and UpdatedAt keep track of when this record was created
// or modified.
CreatedAt , UpdatedAt time . Time
CreateIndex uint64
ModifyIndex uint64
}
// IntentionAction is the action that the intention represents. This
// can be "allow" or "deny" to whitelist or blacklist intentions.
type IntentionAction string
const (
IntentionActionAllow IntentionAction = "allow"
IntentionActionDeny IntentionAction = "deny"
)
// IntentionSourceType is the type of the source within an intention.
type IntentionSourceType string
const (
// IntentionSourceConsul is a service within the Consul catalog.
IntentionSourceConsul IntentionSourceType = "consul"
)
// IntentionMatch are the arguments for the intention match API.
type IntentionMatch struct {
By IntentionMatchType
Names [ ] string
}
// IntentionMatchType is the target for a match request. For example,
// matching by source will look for all intentions that match the given
// source value.
type IntentionMatchType string
const (
IntentionMatchSource IntentionMatchType = "source"
IntentionMatchDestination IntentionMatchType = "destination"
)
// IntentionCheck are the arguments for the intention check API. For
// more documentation see the IntentionCheck function.
type IntentionCheck struct {
// Source and Destination are the source and destination values to
// check. The destination is always a Consul service, but the source
// may be other values as defined by the SourceType.
Source , Destination string
// SourceType is the type of the value for the source.
SourceType IntentionSourceType
}
// Intentions returns the list of intentions.
func ( h * Connect ) Intentions ( q * QueryOptions ) ( [ ] * Intention , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/connect/intentions" )
r . setQueryOptions ( q )
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out [ ] * Intention
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return out , qm , nil
}
// IntentionGet retrieves a single intention.
func ( h * Connect ) IntentionGet ( id string , q * QueryOptions ) ( * Intention , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/connect/intentions/" + id )
r . setQueryOptions ( q )
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out Intention
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return & out , qm , nil
}
// IntentionMatch returns the list of intentions that match a given source
// or destination. The returned intentions are ordered by precedence where
// result[0] is the highest precedence (if that matches, then that rule overrides
// all other rules).
//
// Matching can be done for multiple names at the same time. The resulting
// map is keyed by the given names. Casing is preserved.
func ( h * Connect ) IntentionMatch ( args * IntentionMatch , q * QueryOptions ) ( map [ string ] [ ] * Intention , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/connect/intentions/match" )
r . setQueryOptions ( q )
r . params . Set ( "by" , string ( args . By ) )
for _ , name := range args . Names {
r . params . Add ( "name" , name )
}
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return nil , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out map [ string ] [ ] * Intention
if err := decodeBody ( resp , & out ) ; err != nil {
return nil , nil , err
}
return out , qm , nil
}
// IntentionCheck returns whether a given source/destination would be allowed
// or not given the current set of intentions and the configuration of Consul.
func ( h * Connect ) IntentionCheck ( args * IntentionCheck , q * QueryOptions ) ( bool , * QueryMeta , error ) {
r := h . c . newRequest ( "GET" , "/v1/connect/intentions/check" )
r . setQueryOptions ( q )
r . params . Set ( "source" , args . Source )
r . params . Set ( "destination" , args . Destination )
if args . SourceType != "" {
r . params . Set ( "source-type" , string ( args . SourceType ) )
}
rtt , resp , err := requireOK ( h . c . doRequest ( r ) )
if err != nil {
return false , nil , err
}
defer resp . Body . Close ( )
qm := & QueryMeta { }
parseQueryMeta ( resp , qm )
qm . RequestTime = rtt
var out struct { Allowed bool }
if err := decodeBody ( resp , & out ) ; err != nil {
return false , nil , err
}
return out . Allowed , qm , nil
}
// IntentionCreate will create a new intention. The ID in the given
// structure must be empty and a generate ID will be returned on
// success.
func ( c * Connect ) IntentionCreate ( ixn * Intention , q * WriteOptions ) ( string , * WriteMeta , error ) {
r := c . c . newRequest ( "POST" , "/v1/connect/intentions" )
r . setWriteOptions ( q )
r . obj = ixn
rtt , resp , err := requireOK ( c . c . doRequest ( r ) )
if err != nil {
return "" , nil , err
}
defer resp . Body . Close ( )
wm := & WriteMeta { }
wm . RequestTime = rtt
var out struct { ID string }
if err := decodeBody ( resp , & out ) ; err != nil {
return "" , nil , err
}
return out . ID , wm , nil
}