hashicorp

package
v1.86.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: BSD-3-Clause Imports: 21 Imported by: 0

README

HashiCorp Boundary Adapter

Entity External IDs

The Entity External ID is used directly as the API path segment. The adapter constructs URLs as:

{baseURL}/v1/{entityExternalID}?page_size={n}&recursive=true&scope_id={scope}
Entity External ID Parent Entity Description
hosts host-catalogs Boundary hosts (fetched per host catalog)
host-sets host-catalogs Boundary host sets (fetched per host catalog)
credentials credential-stores Stored credentials (fetched per credential store)
credential-libraries credential-stores Credential libraries (fetched per credential store)
accounts auth-methods User accounts (fetched per auth method)
host-catalogs (none) Host catalogs (top-level)
credential-stores (none) Credential stores (top-level)
auth-methods (none) Authentication methods (top-level)

Parent-Child Relationships

Five entities are children that require iterating through a parent collection first:

Child Parent Query Param Added
hosts host-catalogs host_catalog_id={parentID}
host-sets host-catalogs host_catalog_id={parentID}
credentials credential-stores credential_store_id={parentID}
credential-libraries credential-stores credential_store_id={parentID}
accounts auth-methods auth_method_id={parentID}

Notes

  • The adapter is open-ended - any valid Boundary resource type (e.g., roles, users, groups) can be used as an entity external ID.
  • Top-level entities are fetched directly without parent iteration.
  • Pagination uses list_token for cursor-based pagination.

Adding New Entity External IDs

No code changes required for top-level entities. The adapter appends any entity external ID directly to the URL path (/v1/{entityExternalID}). Simply configure a new entity in SGNL with the Boundary resource type name (e.g., roles, users, groups, scopes) and it will work.

To add a new child entity (one that requires parent iteration):

  1. Add a constant in datasource.go for the child entity.
  2. Add a routing case in the GetPage function that maps the child to its parent entity and the query parameter to include (following the pattern of hosts -> host-catalogs with host_catalog_id).
  3. Add the entity to CursorsWithParentEntity in validation.go.
  4. Add tests.

Documentation

Index

Constants

View Source
const (
	EntityTypeHosts               = "hosts"
	EntityTypeHostSets            = "host-sets"
	EntityTypeCredentials         = "credentials"
	EntityTypeCredentialLibraries = "credential-libraries"
	EntityTypeAccounts            = "accounts"
	EntityTypeHostCatalogs        = "host-catalogs"
	EntityTypeCredentialStores    = "credential-stores"
	EntityTypeAuthMethods         = "auth-methods"

	ParamHostCatalogID     = "host_catalog_id"
	ParamCredentialStoreID = "credential_store_id"
	ParamAuthMethodID      = "auth_method_id"

	APIVersion = "v1"
)

Variables

View Source
var (
	CursorsWithParentEntity = map[string]struct{}{
		EntityTypeAccounts:            {},
		EntityTypeCredentials:         {},
		EntityTypeCredentialLibraries: {},
		EntityTypeHosts:               {},
		EntityTypeHostSets:            {},
	}
)

Functions

func ConstructEndpoint

func ConstructEndpoint(request *Request) string

ConstructEndpoint constructs and returns the endpoint to query the datasource.

func NewAdapter

func NewAdapter(client Client) framework.Adapter[Config]

NewAdapter creates a new instance of the HashiCorp adapter with the provided client. It implements the framework.Adapter interface with Config type parameter.

func ParseResponse

func ParseResponse(body []byte) (objects []map[string]any, nextCursor *string, err *framework.Error)

Types

type Adapter

type Adapter struct {
	HashicorpClient Client
	SSRFValidator   validation.SSRFValidator
}

Adapter implements the framework.Adapter interface to query pages of objects from datasources. It handles pagination and authentication for HashiCorp API requests.

func (*Adapter) GetPage

func (a *Adapter) GetPage(ctx context.Context, request *framework.Request[Config]) framework.Response

GetPage is called by SGNL's ingestion service to query a page of objects from a datasource. It validates the request and delegates the actual data fetching to RequestPageFromDatasource.

func (*Adapter) RequestPageFromDatasource

func (a *Adapter) RequestPageFromDatasource(
	ctx context.Context, request *framework.Request[Config],
) framework.Response

RequestPageFromDatasource handles the actual data fetching from the HashiCorp API. It processes the request configuration, handles pagination, and converts the response into the expected format for SGNL's ingestion service.

func (*Adapter) ValidateGetPageRequest

func (a *Adapter) ValidateGetPageRequest(ctx context.Context, request *framework.Request[Config]) *framework.Error

ValidateGetPageRequest validates the fields of the GetPage Request.

type Auth

type Auth struct {
	Username     string
	Password     string
	AuthMethodID string
}

type AuthResponse

type AuthResponse struct {
	Attributes struct {
		Token string `json:"token"`
	} `json:"attributes"`
	Command string `json:"command"`
}

type Client

type Client interface {
	GetPage(ctx context.Context, request *Request) (*Response, *framework.Error)
}

Client is a client that allows querying the HashiCorp datasource which contains JSON objects.

func NewClient

func NewClient(client *http.Client) Client

NewClient returns a Client to query the datasource.

type Config

type Config struct {
	// Common configuration
	*config.CommonConfig

	AuthMethodID string `json:"authMethodId,omitempty"`

	EntityConfig map[string]EntityConfig `json:"entityConfig,omitempty"`
}

func (*Config) Validate

func (c *Config) Validate(_ context.Context) error

ValidateConfig validates that a Config received in a GetPage call is valid.

type Datasource

type Datasource struct {
	Client *http.Client
}

Datasource directly implements a Client interface to allow querying an external datasource.

func (*Datasource) GetPage

func (d *Datasource) GetPage(ctx context.Context, request *Request) (*Response, *framework.Error)

type DatasourceResponse

type DatasourceResponse struct {
	Items        []map[string]any `json:"items"`
	ResponseType string           `json:"response_type"`
	ListToken    string           `json:"list_token"`
	SortBy       string           `json:"sort_by"`
	SortDir      string           `json:"sort_dir"`
	EstItemCount int              `json:"est_item_count"`
}

type EntityConfig

type EntityConfig struct {
	ScopeID string `json:"scopeId,omitempty"`

	Filter string `json:"filter,omitempty"`
}

Config is the configuration passed in each GetPage calls to the adapter. Adapter configuration example: nolint: godot

{
    "requestTimeoutSeconds": 10,
	"authMethodId": "test-auth-method-id",
	"entityConfig": {
		"hosts": {
			"scope_id": "global",
			"filter": ""
		}
	}
}

type Request

type Request struct {
	// BaseURL is the Base URL of the datasource to query.
	BaseURL string

	// Auth is the authentication information to authenticate a request.
	Auth

	// PageSize is the maximum number of objects to return from the entity.
	PageSize int64

	// EntityExternalID is the external ID of the entity.
	// The external ID should match the API's resource name.
	EntityExternalID string

	// Cursor identifies the first object of the page to return, as returned by
	// the last request for the entity.
	// nil in the request for the first page.
	Cursor *pagination.CompositeCursor[string]

	// Filter contains the optional filter to apply to the current request.
	Filter *string

	// Attributes contains the list of attributes to request along with the current request.
	Attributes []*framework.AttributeConfig

	// RequestTimeoutSeconds is the timeout duration for requests made to datasources.
	// This should be set to the number of seconds to wait before timing out.
	RequestTimeoutSeconds int

	// EntityConfig is the configuration for the each entity.
	EntityConfig map[string]EntityConfig

	AdditionalParams map[string]string
	// contains filtered or unexported fields
}

Request is a request to HashiCorp.

type Response

type Response struct {
	// StatusCode is an HTTP status code.
	StatusCode int

	// Objects is the list of
	// May be empty.
	Objects []map[string]any

	// NextCursor is the cursor that identifies the first object of the next page.
	// nil if this is the last page in this full sync.
	NextCursor *string

	// RetryAfter is the number of seconds to wait before retrying the request.
	RetryAfterHeader string
}

Response is a response returned by the datasource.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL