diff --git a/apstra/api_design_interface_maps.go b/apstra/api_design_interface_maps.go index c464945..5811f45 100644 --- a/apstra/api_design_interface_maps.go +++ b/apstra/api_design_interface_maps.go @@ -369,6 +369,13 @@ func (o *Client) getInterfaceMapByName(ctx context.Context, desired string) (*ra } func (o *Client) createInterfaceMap(ctx context.Context, in *InterfaceMapData) (ObjectId, error) { + for _, intf := range in.Interfaces { + err := intf.Roles.Validate() + if err != nil { + return "", err + } + } + response := &objectIdResponse{} return response.Id, o.talkToApstra(ctx, &talkToApstraIn{ method: http.MethodPost, @@ -379,6 +386,13 @@ func (o *Client) createInterfaceMap(ctx context.Context, in *InterfaceMapData) ( } func (o *Client) updateInterfaceMap(ctx context.Context, id ObjectId, in *InterfaceMapData) error { + for _, intf := range in.Interfaces { + err := intf.Roles.Validate() + if err != nil { + return err + } + } + return o.talkToApstra(ctx, &talkToApstraIn{ method: http.MethodPut, urlStr: fmt.Sprintf(apiUrlDesignInterfaceMapById, id), diff --git a/apstra/client.go b/apstra/client.go index 3c1a045..3e2ceef 100644 --- a/apstra/client.go +++ b/apstra/client.go @@ -1054,12 +1054,30 @@ func (o *Client) GetLogicalDeviceByName(ctx context.Context, name string) (*Logi // CreateLogicalDevice creates a new logical device, returns its ObjectId func (o *Client) CreateLogicalDevice(ctx context.Context, in *LogicalDeviceData) (ObjectId, error) { + for _, panel := range in.Panels { + for _, portGroup := range panel.PortGroups { + err := portGroup.Roles.Validate() + if err != nil { + return "", err + } + } + } + return o.createLogicalDevice(ctx, in.raw()) } // UpdateLogicalDevice replaces the whole logical device configuration specified // by id with the supplied details. func (o *Client) UpdateLogicalDevice(ctx context.Context, id ObjectId, in *LogicalDeviceData) error { + for _, panel := range in.Panels { + for _, portGroup := range panel.PortGroups { + err := portGroup.Roles.Validate() + if err != nil { + return err + } + } + } + return o.updateLogicalDevice(ctx, id, in.raw()) } diff --git a/apstra/enum/enum.go b/apstra/enum/enum.go index 2a775b7..9eb7b7f 100644 --- a/apstra/enum/enum.go +++ b/apstra/enum/enum.go @@ -247,7 +247,8 @@ var ( PortRoleAccess, PortRoleGeneric, // todo: remove PortRoleL3Server. Then: - // - remove TestLogicalDevicePortRoles_SetAll + // - remove TestLogicalDevicePortRoles_SetAll() + // - remove LogicalDevicePortRoles.Validate() // - simplify LogicalDevicePortRoles.SetAll() PortRoleL3Server, PortRoleLeaf, diff --git a/apstra/logical_device_port_roles.go b/apstra/logical_device_port_roles.go index 554353d..da8a005 100644 --- a/apstra/logical_device_port_roles.go +++ b/apstra/logical_device_port_roles.go @@ -5,6 +5,7 @@ package apstra import ( + "fmt" "sort" "github.com/Juniper/apstra-go-sdk/apstra/enum" @@ -62,3 +63,17 @@ func (o *LogicalDevicePortRoles) Sort() { return clone[i].Value < clone[j].Value }) } + +func (o *LogicalDevicePortRoles) Validate() error { + if o == nil { + return nil + } + + for _, ldpr := range *o { + if ldpr == enum.PortRoleL3Server { + return fmt.Errorf("logical device port role %q is no longer supported", ldpr.String()) + } + } + + return nil +} diff --git a/apstra/logical_device_port_roles_unit_test.go b/apstra/logical_device_port_roles_unit_test.go index b4199bc..c0b3ea2 100644 --- a/apstra/logical_device_port_roles_unit_test.go +++ b/apstra/logical_device_port_roles_unit_test.go @@ -126,3 +126,41 @@ func TestLogicalDevicePortRoles_SetAll(t *testing.T) { require.Equal(t, expected, data) } + +func TestLogicalDevicePortRoles_Validate(t *testing.T) { + type testCase struct { + roles []string + errContains string + } + + testCases := map[string]testCase{ + "okay": { + roles: []string{"access", "leaf", "spine"}, + }, + "empty": {}, + "single_err": { + roles: []string{"l3_server"}, + errContains: "l3_server", + }, + "multiple_err": { + roles: []string{"access", "l3_server", "spine"}, + errContains: "l3_server", + }, + } + + for tName, tCase := range testCases { + t.Run(tName, func(t *testing.T) { + var portRoles apstra.LogicalDevicePortRoles + err := portRoles.FromStrings(tCase.roles) + require.NoError(t, err) + + err = portRoles.Validate() + if tCase.errContains != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tCase.errContains) + } else { + require.NoError(t, err) + } + }) + } +}