cloud

package module
v0.5.12 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2023 License: MIT Imports: 19 Imported by: 0

README

Cisco pxGrid Cloud SDK for Go

Tests Static Analysis Release Docs

Overview

cloud-sdk-go is the Cisco pxGrid Cloud SDK for the Go programming language. This SDK requires a minimum version of Go 1.18.

The SDK lets you easily create applications for Cisco pxGrid Cloud and consume pxGrid, ERS and OpenAPI services from Cisco Identity Services Engine (ISE) devices.

Features

  • Multi-tenancy support
  • Create an instance of an application
  • Link application with a Cisco DNA - Cloud tenant
  • Receive pxGrid topic messages from Cisco ISE devices
  • Invoke HTTP APIs on Cisco ISE devices
    • pxGrid APIs
    • ERS APIs
    • OpenAPI APIs

Install

go get github.com/cisco-pxgrid/cloud-sdk-go

Usage

Examples

Create a new app instance
import (
    "fmt"
    sdk "github.com/cisco-pxgrid/cloud-sdk-go"
)

// activationHandler is invoked when the app gets activated for a new device for a tenant
func activationHandler(device *sdk.Device) {
    fmt.Printf("New device activated: %s\n", device)
}

// deactivationHandler is invoked when the app gets deactivated for an existing device for a tenant
func deactivationHandler(device *sdk.Device) {
    fmt.Printf("Device deactivated: %s\n", device)
}

// messageHandler is invoked when there's a new message received by the app for a device
func messageHandler(id string, device *sdk.Device, stream string, payload []byte) {
    fmt.Printf("Received new message (%s) from %s\n", id, device)
    fmt.Printf("Message stream: %s\n", stream)
    fmt.Printf("Message payload: %s\n", payload)
}

// getCredentials is invoked whenever the app needs to retrieve the app credentials
func getCredentials() (*sdk.Credentials, error) {
    return &sdk.Credentials{
        ApiKey: []byte("api-key-obtained-during-app-onboarding"),
    }, nil
}

func main() {
    // create app configuration required for creating a new app instance
    config := sdk.Config{
        ID:                        "pxgrid-cloud-sample-app",
        GetCredentials:            getCredentials,
        RegionalFQDN:              "regional.cloud.cisco.com",
        GlobalFQDN:                "global.cloud.cisco.com",
        DeviceActivationHandler:   activationHandler,
        DeviceDeactivationHandler: deactivationHandler,
        DeviceMessageHandler:      messageHandler,
        ReadStreamID:              "app--pxgrid-cloud-sample-app-R",
        WriteStreamID:             "app--pxgrid-cloud-sample-app-W",
    }

   	app, err := sdk.New(config)
    if err != nil {
        fmt.Printf("Failed to create new app: %v", err)
        os.Exit(1)
    }
    // make sure to Close() the app instance to release resources acquired during app creation
    defer func() {
        if err := app.Close(); err != nil {
            fmt.Printf("Disconnected with error: %v", err)
        }
    }()

    // wait for any errors from the app instance created above
    err = <- app.Error
    if err != nil {
        fmt.Printf("%s received an error: %v", app, err)
    }
}
tenant, err := app.LinkTenant("otp-obtained-from-cisco-dna-portal")
if err != nil {
    fmt.Printf("Failed to obtain tenant information using supplied OTP: %v", err)
}

// Securely store tenant.ID(), tenant.Name() and tenant.ApiToken()

err = app.UnlinkTenant(tenant)
if err != nil {
    fmt.Printf("Failed to unlink %s from %s: %v", tenant, app, err)
}
Setup already linked tenants

If the app needs to be restarted, use the stored tenant info to re-link.

tenant, err := app.SetTenant("tenant-id", "tenant-name", "tenant-api-token")
if err != nil {
    fmt.Printf("Failed to set tenant: %v", err)
}
Create app instances

If the app is registered as multi-instance, create and delete app instances can be used.

// With the parent app object, create an app instance
appInstance, err = app.CreateAppInstance(ac.Name)

// Securely store appInstance.ID(), appInstance.ApiKey()

// appInstance can then be used to LinkTenant
tenant, err = appInstance.LinkTenant("otp-obtained-from-cisco-dna-portal")

// When finish, delete app instance with parent app
app.DeleteAppInstance(appInstance.ID())

Invoke an ERS or OpenAPI HTTP API call on a device

ERS and OpenAPI URLs start with "/ers" and "/api" respectively.

API guide and reference

req, _ := http.NewRequest(http.MethodGet, "/ers/config/op/systemconfig/iseversion", nil)
resp, err := device.Query(req)
if err != nil {
    fmt.Printf("Failed to invoke %s on %s: %v", req, device, err)
}
Invoke pxGrid HTTP API on a device

pxGrid Reference

In order to invoke pxGrid APIs directly on the device, ServiceLookup is not required. Instead map the service name to the keyword and append it to the URL along with pxgrid

pxGrid Service pxGrid Cloud Service
com.cisco.ise.session session
com.cisco.ise.config.anc anc
com.cisco.ise.mdm mdm
com.cisco.ise.config.profiler profiler
com.cisco.ise.radius radius
com.cisco.ise.trustsec trustsec
com.cisco.ise.config.trustsec trustsec
com.cisco.ise.sxp trustsec
com.cisco.ise.echo echo
req, _ := http.NewRequest(http.MethodPost, "/pxgrid/trustsec/getSecurityGroups", strings.NewReader("{}"))
resp, err := device.Query(req)
if err != nil {
    fmt.Printf("Failed to invoke %s on %s: %v", req, device, err)
}
Query limitation

There is currently a limitation on the payload size

Size From ISE versions
500KB 3.1 patch 3, 3.2
50MB 3.2 patch 2, 3.3
Stream names mappings

These are the mappings of pxGrid Cloud stream names from pxGrid topic

pxGrid Service pxGrid property name pxGrid Cloud stream name
com.cisco.ise.session sessionTopic pxcloud--session-sessions
com.cisco.ise.session groupTopic pxcloud--session-userGroups
com.cisco.ise.config.anc statusTopic pxcloud--anc-operationStatus
com.cisco.ise.mdm endpointTopic pxcloud--mdm-endpoints
com.cisco.ise.config.profiler topic pxcloud--profiler-profiles
com.cisco.ise.radius failureTopic pxcloud--radius-failures
com.cisco.ise.trustsec policyDownloadTopic pxcloud--trustsec-policyDownloads
com.cisco.ise.config.trustsec securityGroupTopic pxcloud--trustsec-securityGroups
com.cisco.ise.config.trustsec securityGroupAclTopic pxcloud--trustsec-securityGroupAcls
com.cisco.ise.sxp bindingTopic pxcloud--trustsec-bindings
com.cisco.ise.echo echoTopic pxcloud--echo-echo

Terminology

  • App: An app represents an application that's available on the Cisco DNA - Cloud App Store.
  • Tenant: A tenant represents a Cisco customer that subscribes to and intends to use services Cisco DNA - Cloud services.
  • Device: A device represents an on-premise entity (an appliance, a VM, a deployment, a cluster, etc.) that is registered with the Cisco DNA - Cloud. Cisco ISE is such an example.

Documentation

Index

Constants

View Source
const (
	X_API_PROXY_COMMUNICATION_SYTLE = "X-Api-Proxy-Communication-Style"
)

Variables

View Source
var (
	RequestBodyMax   = 300 * 1024
	RequestObjectMax = 100 * 1024 * 1024
	//2GB
	MultipartRequestObjectMax = 2 * 1024 * 1024 * 1024
	//50MB
	PartSize          = 50 * 1024 * 1024
	StatusPollTimeMin = 500 * time.Millisecond
	StatusPollTimeMax = 15 * time.Second
)

Functions

This section is empty.

Types

type App

type App struct {

	// Error channel should be used to monitor any errors
	Error chan error
	// contains filtered or unexported fields
}

App represents an instance of a pxGrid Cloud Application App struct is the entry point for the pxGrid Cloud Go SDK

func New

func New(config Config) (*App, error)

New creates and returns a new instance of App New accepts Config argument which is used to construct http clients, transport layer and setup PubSub configuration

func (*App) ApiKey added in v0.5.7

func (app *App) ApiKey() string

func (*App) Close

func (app *App) Close() error

Close shuts down the App instance and releases all the resources

func (*App) CreateAppInstance added in v0.5.11

func (app *App) CreateAppInstance(instanceName string) (*App, error)

CreateAppInstance creates an app instance. The instance can then be used to LinkTenant. This is called with the parent app, using the parent app_key to authenticate InstanceName will be shown in UI to signify the new application instance. The returned App.ID() and App.ApiKey() must be stored securely. This can only be used with application that is registered as multi-instance.

func (*App) DeleteAppInstance added in v0.5.11

func (app *App) DeleteAppInstance(instanceAppId string) error

DeleteAppInstance deletes an app instance using the AppId of the instance This is called with the parent app, using the parent app_key to authenticate.

func (*App) ID added in v0.5.7

func (app *App) ID() string

func (*App) LinkTenant

func (app *App) LinkTenant(otp string) (*Tenant, error)

LinkTenant redeems the OTP and links a tenant to the application Returned tenant must be stored securely

func (*App) LinkTenantWithNewAppInstance deprecated added in v0.5.7

func (app *App) LinkTenantWithNewAppInstance(otp, instanceName string) (*App, *Tenant, error)

LinkTenantWithNewAppInstance redeems the OTP and links a tenant to a new application instance. InstanceName will be shown in UI to signify the new application instance. The returned App.ID(), App.ApiKey(), Tenant.ID(), Tenant.Name() and Tenant.ApiToken() must be stored securely.

Deprecated: Use CreateAppInstance and LinkTenant instead.

func (*App) SetAppInstance added in v0.5.7

func (app *App) SetAppInstance(appID, appApiKey string) (*App, error)

SetAppInstance adds an application instance. The appID and appApiKey are obtained from calling LinkTenantWithNewAppInstance. This should be used by application after restart to reload application instances

func (*App) SetTenant

func (app *App) SetTenant(id, name, apiToken string) (*Tenant, error)

SetTenant adds linked tenant to the application's inner infrastructure SetTenant should be used by application after restart to reload tenants back

func (*App) String

func (app *App) String() string

func (*App) UnlinkTenant

func (app *App) UnlinkTenant(tenant *Tenant) error

UnlinkTenant unlinks a tenant from the application The stored tenant ID, name and token should be discarded

type Config

type Config struct {
	// ID is the unique application identifier obtained during app onboarding
	ID string

	// Hostname of the regional cloud environment
	RegionalFQDN string

	// Hostname of the global cloud environment
	GlobalFQDN string

	// ReadStreamID is the stream with "R" access obtained during app onboarding
	ReadStreamID string

	// WriteStreamID is the stream with "W" access obtained during app onboarding
	WriteStreamID string

	// GroupID defines the group in which this instance of the App belongs to. Instances that belong
	// in the same group gets messages distributed between them. Instances that belong in separate
	// groups get a copy of each message. If left empty, unique ID will be used.
	//
	// e.g. There are 3 messages on the app's stream - msg1, msg2, msg3
	//
	// If there are 2 app instances of the same app with same group ID, the 3 messages are
	// distributed between both the instances.
	// If there are 2 app instances of the same app with different group IDs, then each instance
	// receives all 3 messages.
	GroupID string

	// Transport (if set) will be used for any HTTP connection establishment by the SDK
	Transport *http.Transport

	// GetCredentials is used to retrieve the client credentials provided to the app during onboarding
	// Either use this or ApiKey
	GetCredentials func() (*Credentials, error)

	// ApiKey is used when GetCredentials is not specified
	ApiKey string

	// DeviceActivationHandler notifies when a device is activated
	DeviceActivationHandler func(device *Device)

	// DeviceDeactivationHandler notifies when a device is deactivated
	DeviceDeactivationHandler func(device *Device)

	// TenantUnlinkedHandler notifies when a tenant is unlinked from the cloud instead of app calling UnlinkTenant
	// Not providing a linked handler because it can only be triggered by calling LinkTenant
	// The stored tenant ID, name and token should be discarded
	TenantUnlinkedHandler func(tenant *Tenant)

	// DeviceMessageHandler is invoked when a new data message is received
	DeviceMessageHandler func(messageID string, device *Device, stream string, payload []byte)
}

Config defines the configuration for an application

type Credentials

type Credentials struct {
	// ApiKey is obtained during app onboarding with dragonfly
	// ApiKey will be zeroed after use, therefore AppConfig.GetCredentials function should provide new structure every invocation
	ApiKey []byte
}

Credentials are fields that is used for request authorization Credentials required to be stored securely

type Device

type Device struct {
	// contains filtered or unexported fields
}

Device represents an ISE deployment that's registered with pxGrid Cloud

func (*Device) ID

func (d *Device) ID() string

ID returns device's id

func (*Device) MarshalJSON

func (d *Device) MarshalJSON() ([]byte, error)

func (*Device) Name

func (d *Device) Name() string

Name returns device's name

func (*Device) Query

func (d *Device) Query(request *http.Request) (*http.Response, error)

Query for pxGrid, ERS or other API Hostname, authentication will be filled by the SDK Underlying direct mode with API-Proxy Context, URL, headers, body...etc can be set within request

func (*Device) Region

func (d *Device) Region() string

Region returns device's region

func (*Device) Status

func (d *Device) Status() (*DeviceStatus, error)

Status fetches actual status of the device

func (*Device) String

func (d *Device) String() string

func (*Device) Tenant

func (d *Device) Tenant() *Tenant

Tenant returns device's tenant

func (*Device) Type

func (d *Device) Type() string

Type returns device's type

type DeviceStatus

type DeviceStatus struct {
	Status string
}

DeviceStatus represents the status of a device

type Tenant

type Tenant struct {
	// contains filtered or unexported fields
}

Tenant represents a tenant that has been linked to the application via OTP redemption This has to be stored securely by the application. During restart, application is required to reload it back to use using App.SetTenant function

func (*Tenant) ApiToken

func (t *Tenant) ApiToken() string

ApiToken returns tenant's api token

func (*Tenant) GetDevice

func (t *Tenant) GetDevice(deviceId string) (*Device, error)

GetDevice returns information for a specific device

func (*Tenant) GetDevices

func (t *Tenant) GetDevices() ([]Device, error)

GetDevices gets a list of devices registered for the tenant

func (*Tenant) ID

func (t *Tenant) ID() string

ID returns tenant's id

func (*Tenant) MarshalJSON

func (t *Tenant) MarshalJSON() ([]byte, error)

func (*Tenant) Name

func (t *Tenant) Name() string

Name returns tenant's name

func (*Tenant) String

func (t *Tenant) String() string

Directories

Path Synopsis
examples
internal
pubsub
Package pubsub implements functionality to interact with DxHub using PubSub semantics.
Package pubsub implements functionality to interact with DxHub using PubSub semantics.
rpc
Package rpc implements JSON RPC protocol used by DxHub PubSub
Package rpc implements JSON RPC protocol used by DxHub PubSub
Package log provides logging functionality for the SDK
Package log provides logging functionality for the SDK

Jump to

Keyboard shortcuts

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