k3s/vendor/github.com/Microsoft/hcsshim/hcn/hcnerrors.go
2020-08-28 17:18:31 -07:00

165 lines
4.2 KiB
Go

// Package hcn is a shim for the Host Compute Networking (HCN) service, which manages networking for Windows Server
// containers and Hyper-V containers. Previous to RS5, HCN was referred to as Host Networking Service (HNS).
package hcn
import (
"errors"
"fmt"
"github.com/Microsoft/hcsshim/internal/hcs"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus"
)
var (
errInvalidNetworkID = errors.New("invalid network ID")
errInvalidEndpointID = errors.New("invalid endpoint ID")
errInvalidNamespaceID = errors.New("invalid namespace ID")
errInvalidLoadBalancerID = errors.New("invalid load balancer ID")
errInvalidRouteID = errors.New("invalid route ID")
)
func checkForErrors(methodName string, hr error, resultBuffer *uint16) error {
errorFound := false
if hr != nil {
errorFound = true
}
result := ""
if resultBuffer != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultBuffer)
if result != "" {
errorFound = true
}
}
if errorFound {
returnError := new(hr, methodName, result)
logrus.Debugf(returnError.Error()) // HCN errors logged for debugging.
return returnError
}
return nil
}
type ErrorCode uint32
// For common errors, define the error as it is in windows, so we can quickly determine it later
const (
ERROR_NOT_FOUND = 0x490
HCN_E_PORT_ALREADY_EXISTS ErrorCode = 0x803b0013
)
type HcnError struct {
*hcserror.HcsError
code ErrorCode
}
func (e *HcnError) Error() string {
return e.HcsError.Error()
}
func CheckErrorWithCode(err error, code ErrorCode) bool {
hcnError, ok := err.(*HcnError)
if ok {
return hcnError.code == code
}
return false
}
func IsElementNotFoundError(err error) bool {
return CheckErrorWithCode(err, ERROR_NOT_FOUND)
}
func IsPortAlreadyExistsError(err error) bool {
return CheckErrorWithCode(err, HCN_E_PORT_ALREADY_EXISTS)
}
func new(hr error, title string, rest string) error {
err := &HcnError{}
hcsError := hcserror.New(hr, title, rest)
err.HcsError = hcsError.(*hcserror.HcsError)
err.code = ErrorCode(hcserror.Win32FromError(hr))
return err
}
//
// Note that the below errors are not errors returned by hcn itself
// we wish to seperate them as they are shim usage error
//
// NetworkNotFoundError results from a failed seach for a network by Id or Name
type NetworkNotFoundError struct {
NetworkName string
NetworkID string
}
func (e NetworkNotFoundError) Error() string {
if e.NetworkName != "" {
return fmt.Sprintf("Network name %q not found", e.NetworkName)
}
return fmt.Sprintf("Network ID %q not found", e.NetworkID)
}
// EndpointNotFoundError results from a failed seach for an endpoint by Id or Name
type EndpointNotFoundError struct {
EndpointName string
EndpointID string
}
func (e EndpointNotFoundError) Error() string {
if e.EndpointName != "" {
return fmt.Sprintf("Endpoint name %q not found", e.EndpointName)
}
return fmt.Sprintf("Endpoint ID %q not found", e.EndpointID)
}
// NamespaceNotFoundError results from a failed seach for a namsepace by Id
type NamespaceNotFoundError struct {
NamespaceID string
}
func (e NamespaceNotFoundError) Error() string {
return fmt.Sprintf("Namespace ID %q not found", e.NamespaceID)
}
// LoadBalancerNotFoundError results from a failed seach for a loadbalancer by Id
type LoadBalancerNotFoundError struct {
LoadBalancerId string
}
func (e LoadBalancerNotFoundError) Error() string {
return fmt.Sprintf("LoadBalancer %q not found", e.LoadBalancerId)
}
// RouteNotFoundError results from a failed seach for a route by Id
type RouteNotFoundError struct {
RouteId string
}
func (e RouteNotFoundError) Error() string {
return fmt.Sprintf("SDN Route %q not found", e.RouteId)
}
// IsNotFoundError returns a boolean indicating whether the error was caused by
// a resource not being found.
func IsNotFoundError(err error) bool {
switch pe := err.(type) {
case NetworkNotFoundError:
return true
case EndpointNotFoundError:
return true
case NamespaceNotFoundError:
return true
case LoadBalancerNotFoundError:
return true
case RouteNotFoundError:
return true
case *hcserror.HcsError:
return pe.Err == hcs.ErrElementNotFound
}
return false
}