mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-13 10:21:10 +01:00
Merge pull request #3025 from netbirdio/feature/add-policy-network-resources
[management] Extends policy with source and destination resources
This commit is contained in:
commit
7944b8e843
@ -782,15 +782,18 @@ components:
|
||||
items:
|
||||
type: string
|
||||
example: "ch8i4ug6lnn4g9hqv797"
|
||||
sourceResource:
|
||||
description: Policy rule source resource that the rule is applied to
|
||||
$ref: '#/components/schemas/Resource'
|
||||
destinations:
|
||||
description: Policy rule destination group IDs
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: "ch8i4ug6lnn4g9h7v7m0"
|
||||
required:
|
||||
- sources
|
||||
- destinations
|
||||
destinationResource:
|
||||
description: Policy rule destination resource that the rule is applied to
|
||||
$ref: '#/components/schemas/Resource'
|
||||
PolicyRule:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/PolicyRuleMinimum'
|
||||
@ -801,14 +804,17 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/GroupMinimum'
|
||||
sourceResource:
|
||||
description: Policy rule source resource that the rule is applied to
|
||||
$ref: '#/components/schemas/Resource'
|
||||
destinations:
|
||||
description: Policy rule destination group IDs
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/GroupMinimum'
|
||||
required:
|
||||
- sources
|
||||
- destinations
|
||||
destinationResource:
|
||||
description: Policy rule destination resource that the rule is applied to
|
||||
$ref: '#/components/schemas/Resource'
|
||||
PolicyMinimum:
|
||||
type: object
|
||||
properties:
|
||||
@ -1176,6 +1182,24 @@ components:
|
||||
- id
|
||||
- network_type
|
||||
- $ref: '#/components/schemas/RouteRequest'
|
||||
Resource:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: ID of the resource
|
||||
type: string
|
||||
example: chacdk86lnnboviihd7g
|
||||
type:
|
||||
description: Type of the resource
|
||||
$ref: '#/components/schemas/ResourceType'
|
||||
required:
|
||||
- id
|
||||
- type
|
||||
ResourceType:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/NetworkResourceType'
|
||||
- type: string
|
||||
example: host
|
||||
NetworkRequest:
|
||||
type: object
|
||||
properties:
|
||||
@ -1227,14 +1251,16 @@ components:
|
||||
type: string
|
||||
example: chacdk86lnnboviihd7g
|
||||
type:
|
||||
description: Network resource type based of the address
|
||||
type: string
|
||||
enum: [ "host", "subnet", "domain"]
|
||||
example: host
|
||||
$ref: '#/components/schemas/NetworkResourceType'
|
||||
required:
|
||||
- id
|
||||
- type
|
||||
- $ref: '#/components/schemas/NetworkResourceRequest'
|
||||
NetworkResourceType:
|
||||
description: Network resource type based of the address
|
||||
type: string
|
||||
enum: [ "host", "subnet", "domain" ]
|
||||
example: host
|
||||
NetworkRouterRequest:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -143,6 +143,13 @@ const (
|
||||
PolicyRuleUpdateProtocolUdp PolicyRuleUpdateProtocol = "udp"
|
||||
)
|
||||
|
||||
// Defines values for ResourceType.
|
||||
const (
|
||||
ResourceTypeDomain ResourceType = "domain"
|
||||
ResourceTypeHost ResourceType = "host"
|
||||
ResourceTypeSubnet ResourceType = "subnet"
|
||||
)
|
||||
|
||||
// Defines values for UserStatus.
|
||||
const (
|
||||
UserStatusActive UserStatus = "active"
|
||||
@ -540,9 +547,6 @@ type NetworkResource struct {
|
||||
Type NetworkResourceType `json:"type"`
|
||||
}
|
||||
|
||||
// NetworkResourceType Network resource type based of the address
|
||||
type NetworkResourceType string
|
||||
|
||||
// NetworkResourceRequest defines model for NetworkResourceRequest.
|
||||
type NetworkResourceRequest struct {
|
||||
// Address Network resource address (either a direct host like 1.1.1.1 or 1.1.1.1/32, or a subnet like 192.168.178.0/24, or a domain like example.com)
|
||||
@ -555,6 +559,9 @@ type NetworkResourceRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// NetworkResourceType Network resource type based of the address
|
||||
type NetworkResourceType string
|
||||
|
||||
// NetworkRouter defines model for NetworkRouter.
|
||||
type NetworkRouter struct {
|
||||
// Id Network Router Id
|
||||
@ -873,10 +880,11 @@ type PolicyRule struct {
|
||||
Bidirectional bool `json:"bidirectional"`
|
||||
|
||||
// Description Policy rule friendly description
|
||||
Description *string `json:"description,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
DestinationResource *Resource `json:"destinationResource,omitempty"`
|
||||
|
||||
// Destinations Policy rule destination group IDs
|
||||
Destinations []GroupMinimum `json:"destinations"`
|
||||
Destinations *[]GroupMinimum `json:"destinations,omitempty"`
|
||||
|
||||
// Enabled Policy rule status
|
||||
Enabled bool `json:"enabled"`
|
||||
@ -894,10 +902,11 @@ type PolicyRule struct {
|
||||
Ports *[]string `json:"ports,omitempty"`
|
||||
|
||||
// Protocol Policy rule type of the traffic
|
||||
Protocol PolicyRuleProtocol `json:"protocol"`
|
||||
Protocol PolicyRuleProtocol `json:"protocol"`
|
||||
SourceResource *Resource `json:"sourceResource,omitempty"`
|
||||
|
||||
// Sources Policy rule source group IDs
|
||||
Sources []GroupMinimum `json:"sources"`
|
||||
Sources *[]GroupMinimum `json:"sources,omitempty"`
|
||||
}
|
||||
|
||||
// PolicyRuleAction Policy rule accept or drops packets
|
||||
@ -951,10 +960,11 @@ type PolicyRuleUpdate struct {
|
||||
Bidirectional bool `json:"bidirectional"`
|
||||
|
||||
// Description Policy rule friendly description
|
||||
Description *string `json:"description,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
DestinationResource *Resource `json:"destinationResource,omitempty"`
|
||||
|
||||
// Destinations Policy rule destination group IDs
|
||||
Destinations []string `json:"destinations"`
|
||||
Destinations *[]string `json:"destinations,omitempty"`
|
||||
|
||||
// Enabled Policy rule status
|
||||
Enabled bool `json:"enabled"`
|
||||
@ -972,10 +982,11 @@ type PolicyRuleUpdate struct {
|
||||
Ports *[]string `json:"ports,omitempty"`
|
||||
|
||||
// Protocol Policy rule type of the traffic
|
||||
Protocol PolicyRuleUpdateProtocol `json:"protocol"`
|
||||
Protocol PolicyRuleUpdateProtocol `json:"protocol"`
|
||||
SourceResource *Resource `json:"sourceResource,omitempty"`
|
||||
|
||||
// Sources Policy rule source group IDs
|
||||
Sources []string `json:"sources"`
|
||||
Sources *[]string `json:"sources,omitempty"`
|
||||
}
|
||||
|
||||
// PolicyRuleUpdateAction Policy rule accept or drops packets
|
||||
@ -1049,6 +1060,16 @@ type ProcessCheck struct {
|
||||
Processes []Process `json:"processes"`
|
||||
}
|
||||
|
||||
// Resource defines model for Resource.
|
||||
type Resource struct {
|
||||
// Id Resource ID
|
||||
Id string `json:"id"`
|
||||
Type ResourceType `json:"type"`
|
||||
}
|
||||
|
||||
// ResourceType defines model for ResourceType.
|
||||
type ResourceType string
|
||||
|
||||
// Route defines model for Route.
|
||||
type Route struct {
|
||||
// AccessControlGroups Access control group identifier associated with route.
|
||||
|
@ -147,15 +147,56 @@ func (h *handler) savePolicy(w http.ResponseWriter, r *http.Request, accountID s
|
||||
ruleID = *rule.Id
|
||||
}
|
||||
|
||||
hasSources := rule.Sources != nil
|
||||
hasSourceResource := rule.SourceResource != nil
|
||||
|
||||
hasDestinations := rule.Destinations != nil
|
||||
hasDestinationResource := rule.DestinationResource != nil
|
||||
|
||||
if hasSources && hasSourceResource {
|
||||
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "specify either sources or source resources, not both"), w)
|
||||
return
|
||||
}
|
||||
|
||||
if hasDestinations && hasDestinationResource {
|
||||
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "specify either destinations or destination resources, not both"), w)
|
||||
return
|
||||
}
|
||||
|
||||
if !(hasSources || hasSourceResource) || !(hasDestinations || hasDestinationResource) {
|
||||
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "specify either sources or source resources and destinations or destination resources"), w)
|
||||
return
|
||||
}
|
||||
|
||||
pr := types.PolicyRule{
|
||||
ID: ruleID,
|
||||
PolicyID: policyID,
|
||||
Name: rule.Name,
|
||||
Destinations: rule.Destinations,
|
||||
Sources: rule.Sources,
|
||||
Bidirectional: rule.Bidirectional,
|
||||
}
|
||||
|
||||
if hasSources {
|
||||
pr.Sources = *rule.Sources
|
||||
}
|
||||
|
||||
if hasSourceResource {
|
||||
// TODO: validate the resource id and type
|
||||
sourceResource := &types.Resource{}
|
||||
sourceResource.FromAPIRequest(rule.SourceResource)
|
||||
pr.SourceResource = *sourceResource
|
||||
}
|
||||
|
||||
if hasDestinations {
|
||||
pr.Destinations = *rule.Destinations
|
||||
}
|
||||
|
||||
if hasDestinationResource {
|
||||
// TODO: validate the resource id and type
|
||||
destinationResource := &types.Resource{}
|
||||
destinationResource.FromAPIRequest(rule.DestinationResource)
|
||||
pr.DestinationResource = *destinationResource
|
||||
}
|
||||
|
||||
pr.Enabled = rule.Enabled
|
||||
if rule.Description != nil {
|
||||
pr.Description = *rule.Description
|
||||
@ -338,13 +379,15 @@ func toPolicyResponse(groups []*nbgroup.Group, policy *types.Policy) *api.Policy
|
||||
rID := r.ID
|
||||
rDescription := r.Description
|
||||
rule := api.PolicyRule{
|
||||
Id: &rID,
|
||||
Name: r.Name,
|
||||
Enabled: r.Enabled,
|
||||
Description: &rDescription,
|
||||
Bidirectional: r.Bidirectional,
|
||||
Protocol: api.PolicyRuleProtocol(r.Protocol),
|
||||
Action: api.PolicyRuleAction(r.Action),
|
||||
Id: &rID,
|
||||
Name: r.Name,
|
||||
Enabled: r.Enabled,
|
||||
Description: &rDescription,
|
||||
Bidirectional: r.Bidirectional,
|
||||
Protocol: api.PolicyRuleProtocol(r.Protocol),
|
||||
Action: api.PolicyRuleAction(r.Action),
|
||||
SourceResource: r.SourceResource.ToAPIResponse(),
|
||||
DestinationResource: r.DestinationResource.ToAPIResponse(),
|
||||
}
|
||||
|
||||
if len(r.Ports) != 0 {
|
||||
@ -363,26 +406,30 @@ func toPolicyResponse(groups []*nbgroup.Group, policy *types.Policy) *api.Policy
|
||||
rule.PortRanges = &portRanges
|
||||
}
|
||||
|
||||
var sources []api.GroupMinimum
|
||||
for _, gid := range r.Sources {
|
||||
_, ok := cache[gid]
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if group, ok := groupsMap[gid]; ok {
|
||||
minimum := api.GroupMinimum{
|
||||
Id: group.ID,
|
||||
Name: group.Name,
|
||||
PeersCount: len(group.Peers),
|
||||
}
|
||||
rule.Sources = append(rule.Sources, minimum)
|
||||
sources = append(sources, minimum)
|
||||
cache[gid] = minimum
|
||||
}
|
||||
}
|
||||
rule.Sources = &sources
|
||||
|
||||
var destinations []api.GroupMinimum
|
||||
for _, gid := range r.Destinations {
|
||||
cachedMinimum, ok := cache[gid]
|
||||
if ok {
|
||||
rule.Destinations = append(rule.Destinations, cachedMinimum)
|
||||
destinations = append(destinations, cachedMinimum)
|
||||
continue
|
||||
}
|
||||
if group, ok := groupsMap[gid]; ok {
|
||||
@ -391,10 +438,12 @@ func toPolicyResponse(groups []*nbgroup.Group, policy *types.Policy) *api.Policy
|
||||
Name: group.Name,
|
||||
PeersCount: len(group.Peers),
|
||||
}
|
||||
rule.Destinations = append(rule.Destinations, minimum)
|
||||
destinations = append(destinations, minimum)
|
||||
cache[gid] = minimum
|
||||
}
|
||||
}
|
||||
rule.Destinations = &destinations
|
||||
|
||||
ap.Rules = append(ap.Rules, rule)
|
||||
}
|
||||
return ap
|
||||
|
@ -177,7 +177,9 @@ func TestPoliciesWritePolicy(t *testing.T) {
|
||||
"Description": "Description",
|
||||
"Protocol": "tcp",
|
||||
"Action": "accept",
|
||||
"Bidirectional":true
|
||||
"Bidirectional":true,
|
||||
"Sources": ["F"],
|
||||
"Destinations": ["G"]
|
||||
}
|
||||
]}`)),
|
||||
expectedStatus: http.StatusOK,
|
||||
@ -193,6 +195,8 @@ func TestPoliciesWritePolicy(t *testing.T) {
|
||||
Protocol: "tcp",
|
||||
Action: "accept",
|
||||
Bidirectional: true,
|
||||
Sources: &[]api.GroupMinimum{{Id: "F"}},
|
||||
Destinations: &[]api.GroupMinimum{{Id: "G"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -221,7 +225,9 @@ func TestPoliciesWritePolicy(t *testing.T) {
|
||||
"Description": "Description",
|
||||
"Protocol": "tcp",
|
||||
"Action": "accept",
|
||||
"Bidirectional":true
|
||||
"Bidirectional":true,
|
||||
"Sources": ["F"],
|
||||
"Destinations": ["F"]
|
||||
}
|
||||
]}`)),
|
||||
expectedStatus: http.StatusOK,
|
||||
@ -237,6 +243,8 @@ func TestPoliciesWritePolicy(t *testing.T) {
|
||||
Protocol: "tcp",
|
||||
Action: "accept",
|
||||
Bidirectional: true,
|
||||
Sources: &[]api.GroupMinimum{{Id: "F"}},
|
||||
Destinations: &[]api.GroupMinimum{{Id: "F"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -41,9 +41,15 @@ type PolicyRule struct {
|
||||
// Destinations policy destination groups
|
||||
Destinations []string `gorm:"serializer:json"`
|
||||
|
||||
// DestinationResource policy destination resource that the rule is applied to
|
||||
DestinationResource Resource `gorm:"serializer:json"`
|
||||
|
||||
// Sources policy source groups
|
||||
Sources []string `gorm:"serializer:json"`
|
||||
|
||||
// SourceResource policy source resource that the rule is applied to
|
||||
SourceResource Resource `gorm:"serializer:json"`
|
||||
|
||||
// Bidirectional define if the rule is applicable in both directions, sources, and destinations
|
||||
Bidirectional bool
|
||||
|
||||
|
30
management/server/types/resource.go
Normal file
30
management/server/types/resource.go
Normal file
@ -0,0 +1,30 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
)
|
||||
|
||||
type Resource struct {
|
||||
ID string
|
||||
Type string
|
||||
}
|
||||
|
||||
func (r *Resource) ToAPIResponse() *api.Resource {
|
||||
if r.ID == "" && r.Type == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &api.Resource{
|
||||
Id: r.ID,
|
||||
Type: api.ResourceType(r.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Resource) FromAPIRequest(req *api.Resource) {
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.ID = req.Id
|
||||
r.Type = string(req.Type)
|
||||
}
|
Loading…
Reference in New Issue
Block a user