ims

package
v1.28.1 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

package ims provides basic support for Incident Management System (IMS) integration, such as ServiceDesk Plus, ServiceNow, etc.

Index

Constants

View Source
const (
	PROFILE              = "__itrs_profile"
	INCIDENT_UPDATE_ONLY = "__incident_update_only"
	INCIDENT_CORRELATION = "__incident_correlation"
)
View Source
const (
	// ServiceNow fields
	SNOW_CMDB_CI_FIELD     = "cmdb_ci"
	SNOW_CORRELATION_FIELD = "correlation_id"
	SNOW_SYS_ID_FIELD      = "sys_id"
	SNOW_USER_NAME_FIELD   = "user_name"

	// ServiceNow tables
	SNOW_SYS_USER_TABLE_DEFAULT = "sys_user"
	SNOW_INCIDENT_TABLE_DEFAULT = "incident"
	SNOW_CMDB_TABLE_DEFAULT     = "cmdb_ci"

	// internal fields
	SNOW_CORRELATION     = "__snow_correlation"
	SNOW_CMDB_CI_DEFAULT = "__snow_cmdb_ci_default"
	SNOW_CMDB_SEARCH     = "__snow_cmdb_search"
	SNOW_CMDB_TABLE      = "__snow_cmdb_table"
	SNOW_INCIDENT_TABLE  = "__snow_table"
)

Variables

View Source
var Endpoints = []Endpoint{}

Functions

func Connect

func Connect(imsCf *config.Config, imsType string) iter.Seq[*rest.Client]

Connect returns a sequence of *ClientConfig for each URL in the configuration. The caller can attempt to connect to each configured URL in turn until a successful connection is made.

The order of the URLs is not guaranteed, so the caller should not rely on the order of the URLs in the configuration. The caller should also be prepared to handle connection failures, as some of the URLs may be unreachable or misconfigured.

The configuration keys suported are:

  • `url`: a list of URLs to connect to, e.g. `["https://ims1.example.com/api", "https://ims2.example.com/api"]`. The IMS type (e.g. `snow`) will be appended, as required by `ims-gateway`, to the URL when creating the client, so the actual URLs used will be `https://ims1.example.com/api/snow` and `https://ims2.example.com/api/snow`.
  • `authentication.token`: the token to use for authentication, e.g. `abc123`
  • `timeout`: the timeout for the connection, e.g. `10s`
  • `tls.skip-verify`: whether to skip TLS verification, e.g. `true`
  • `tls.chain`: a PEM encoded certificate chain to use for TLS verification, e.g. `-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----`
  • `trace`: whether to enable HTTP request/response tracing, e.g. `true`

func CorrelationID

func CorrelationID(data string) string

CorrelationID generates a correlation ID for the given data. The algorithm used, SHA1, does not have to be cryptographically secure, but should produce a reasonably unique ID for the given data. The same data should produce the same correlation ID, and different data should produce different correlation IDs with a very high probability. The correlation ID is returned as a hexadecimal string.

func NewClient

func NewClient(clientConfig *ClientConfig) *rest.Client

NewClient creates a new rest.Client for the given URL and configuration. The client is NOT cached as each execution is a single request to the first remote proxy that responds, however the underlying http.Client is cached and shared across all rest.Client instances created by this function, so TLS configuration is shared across all clients created by this function. The caller should ensure that the TLS configuration is compatible with all URLs that may be used.

func ProcessActionGroup

func ProcessActionGroup(cf *config.Config, ag ActionGroup, incident Values) bool

ProcessActionGroup evaluates the config structure and if the caller should stop processing (break) then returns `true`. The evaluation is in the following order:

  • `if`: one or more strings that are evaluated and the results parsed as a Go boolean (using strconv.ParseBool). As soon as any `if` returns a false value, evaluation stops and the function returns false
  • `set`: an object that sets the fields, unordered, to the value passed through expansion with config.ExpandString
  • `unset`: unset the list of field names
  • `subgroup`: evaluate a sub-group, terminating evaluation if the group includes `break` (after evaluating any `if` actions as true)
  • `break`: break returns true to the caller, allow them to stop processing early. This is used to stop evaluation in a parent
  • `exit`: stops further processing and exits the program immediately with an exit code given. This is used to stop processing in a parent when the child group has done everything needed and no further processing is required.

func RegisterEndpoint

func RegisterEndpoint(method, path string, handler http.HandlerFunc)

RegisterEndpoint registers an API endpoint for the IMS integration, including the HTTP method, path, and handler function. The path should be relative to the application base path and can include path parameters (e.g. "/create/{id}").

func WriteJSONResponse

func WriteJSONResponse(w http.ResponseWriter, r *http.Request, status int) error

WriteJSONResponse writes the given value as JSON to the http.ResponseWriter with the specified status code. If there is an error encoding the value to JSON, it returns the error but does not write an error response to the client, as this function is intended to be used for writing successful responses. The caller should handle writing error responses separately if needed.

Types

type ActionGroup

type ActionGroup struct {
	If       []string          `json:"if,omitempty"`
	Set      map[string]string `json:"set,omitempty"`
	Unset    []string          `json:"unset,omitempty"`
	Subgroup []ActionGroup     `json:"subgroup,omitempty"`
	Break    []string          `json:"break,omitempty"`
	Exit     []string          `json:"exit,omitempty"`
}

type ClientConfig

type ClientConfig struct {
	URL     string        `json:"url,omitempty"`
	Token   string        `json:"token,omitempty"`
	Timeout time.Duration `json:"timeout,omitzero"`

	TLS struct {
		SkipVerify bool   `json:"skip-verify,omitzero"`
		CACerts    []byte `json:"ca-certs,omitempty"`
	} `json:"tls"`

	Trace bool `json:"trace,omitempty"`
}

ClientConfig represents the configuration for creating a new IMS client.

type ContextKey

type ContextKey string
const (
	ContextKeyConfig   ContextKey = "config"   // Context key for passing configuration to handlers, type is *config.Config
	ContextKeyResponse ContextKey = "response" // Context key for passing response to handlers, type is *ims.Response
)

type Endpoint

type Endpoint struct {
	Method  string // HTTP method (e.g. "POST", "GET")
	Path    string // URL path (e.g. "/create", "/update") relative to application base path and including any path parameters (e.g. "/create/{id}")
	Handler http.HandlerFunc
}

Endpoint represents an API endpoint for the IMS integration, including the HTTP method, path, and handler function.

type LogTransport

type LogTransport struct {
	Transport http.RoundTripper
}

LogTransport is a transport for tracing HTTP requests and responses.

func (*LogTransport) RoundTrip

func (t *LogTransport) RoundTrip(req *http.Request) (*http.Response, error)

type Response

type Response struct {
	StartTime    time.Time     `json:"start_time,omitzero"`     // time the request was received by the gateway
	EndTime      time.Time     `json:"end_time,omitzero"`       // time the response is sent by the gateway
	Duration     time.Duration `json:"duration,omitzero"`       // duration of processing the request
	Status       string        `json:"status,omitempty"`        // as per http.Response.Status from remote IMS, empty if request failed before reaching IMS
	StatusCode   int           `json:"status_code,omitempty"`   // as per http.Response.StatusCode from remote IMS, empty if request failed before reaching IMS
	Error        string        `json:"error,omitempty"`         // error message if applicable
	ResultDetail string        `json:"result_detail,omitempty"` // error or success detail if applicable
	Action       string        `json:"action,omitempty"`        // action taken by the gateway, e.g. "Created", "Updated", "Ignored", etc.
	ID           string        `json:"id,omitempty"`            // ID of created or updated incident if applicable
	Data         []string      `json:"data,omitempty"`          // any additional data returned by the gateway, e.g. for query results
	DataTable    [][]string    `json:"data_table,omitempty"`    // table of data, if applicable. first row is column names, subsequent rows are values
	RawResponse  any           `json:"raw_response,omitempty"`
}

Response is the standard response from the IMS gateway, which may include the status code and message from the gateway itself, as well as any data returned by the gateway and the ID of the created or updated incident if applicable. The ProxyResponse field can be used to include the raw response from the proxy for debugging or logging purposes.

type Results

type Results []map[string]string

Results represents the results of an IMS query, which is a slice of maps of string key/value pairs representing the fields and values of each result. This is used for returning query results from the IMS gateway to the client.

type SnowResult

type SnowResult struct {
	Results Results `json:"result,omitempty"`
	Error   struct {
		Message string `json:"message"`
		Detail  string `json:"detail"`
	} `json:"error"`
	Status string `json:"status,omitempty"`
}

SnowResult is the response from ServiceNow. It contains the results of the request, which is a slice of results. It also contains an error message if the request failed. The status field is used to indicate the status of the request. If the request was successful, the status will be "success". If the request failed, the status will be "error". The error field contains the error message and detail if the request failed. The results field contains the results of the request.

type SnowResultsResponse

type SnowResultsResponse struct {
	Fields  []string `json:"fields,omitempty"`
	Results Results  `json:"results,omitempty"`
}

type Transformation added in v1.28.0

type Transformation struct {
	Defaults    map[string]string `mapstructure:"defaults,omitempty"`
	Remove      []string          `mapstructure:"remove,omitempty"`
	Rename      map[string]string `mapstructure:"rename,omitempty"`
	MustInclude []string          `mapstructure:"must-include,omitempty"`
	Include     []string          `mapstructure:"include,omitempty"`
	Exclude     []string          `mapstructure:"exclude,omitempty"`
}

func (Transformation) Transform added in v1.28.0

func (s Transformation) Transform(cf *config.Config, idp string, input map[string]string) (output map[string]string, err error)

Transform applies the Transformation to the given input incident fields and values and returns output. It returns an error if the transformation was not successful and output should not be used

Transformation is applied in the following order:

1. Defaults: For each key/value pair in the `Defaults` map, if the key is not already present in the incident or if the value is empty, the value from the `Defaults` map is added to the incident. The value from the `Defaults` map is expanded using the configuration values in cf, which allows for dynamic values.

2. Remove: For each key in the `Remove` slice, if the key is present in the incident, it is removed from the incident. It is not necessary to include double-underscored (e.g. `__field`) prefixed field names as these are always removed after applying the other stages of the transformation, and in many cases should not be included as they are used in later stages like Rename and MustInclude.

3. Rename:

a. Each input field with the prefix `__IDPNAME_` is renamed to the same name without the prefix. For example, `__IDPNAME_short_description` would be renamed to `short_description`. This allows for fields that are meant to be preserved during renaming to be retained, as they will not be deleted after renaming.

b. For each key/value pair in the `Rename` map, if the key is present in the incident, it is renamed to the value specified in the `Rename` map. If a field is renamed from a name that starts with `__` to a name that does not start with `__`, it will not be deleted after renaming. This allows for fields that are meant to be preserved during renaming to be retained.

4. Exclude: If the `Exclude` slice is not empty, any keys in the incident that do not match any of the regular expressions in the `Exclude` slice are removed from the incident. This allows for filtering out any fields that are not explicitly allowed by the regular expressions in the `Exclude` slice. The regular expressions supported are in Go regexp/syntax(https://pkg.go.dev/regexp/syntax) syntax. If the Exclude slice is empty, no fields are excluded at this stage.

5. Include: If the `Include` slice is not empty, only keys in the incident that match at least one of the regular expressions in the `Include` slice are retained in the incident. This allows for filtering out any fields that are not explicitly allowed by the regular expressions in the `Include` slice. The regular expressions supported are in Go regexp/syntax(https://pkg.go.dev/regexp/syntax) syntax. If the Include slice is empty, all fields are included at this stage.

6. MustInclude: For each key in the `MustInclude` slice, if the key is not present in the incident after applying the previous transformations, an error is returned indicating that a required field is missing. The transformation process is halted at this point if any required fields are missing.

7. Finally, any keys in the incident that start with `__` are removed from the incident, as these are considered internal fields that should not be sent to the remote IMS.

type Values

type Values map[string]string

Values is a simple map of string key/value pairs that can be used to represent incident fields and values. This is used throughout the IMS package to represent the fields and values of an incident, as well as the configuration for a variety of operations.

Jump to

Keyboard shortcuts

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