From e65b9a76fb040282ef690b01bac0acfd8da8a33c Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:28:36 +0300 Subject: [PATCH 1/7] src: added project entity Signed-off-by: Aleksandrov Dmitriy --- src/appConfig.yml | 3 +++ src/domain/AppConfig.go | 3 +++ src/domain/Project.go | 18 ++++++++++++++++++ src/dtos/ProjectBaseDto.go | 6 ++++++ src/dtos/ProjectCreateDto.go | 5 +++++ src/dtos/ProjectDto.go | 11 +++++++++++ src/infrastructure/GormDbInitializer.go | 1 + 7 files changed, 47 insertions(+) create mode 100644 src/domain/Project.go create mode 100644 src/dtos/ProjectBaseDto.go create mode 100644 src/dtos/ProjectCreateDto.go create mode 100644 src/dtos/ProjectDto.go diff --git a/src/appConfig.yml b/src/appConfig.yml index 619871e1..5c9216a1 100644 --- a/src/appConfig.yml +++ b/src/appConfig.yml @@ -4,6 +4,9 @@ httpServer: host: "localhost" port: 8080 +network: + interface: "enp0s8" + # Database config # Currently supports MySQL and SQLite db drivers database: diff --git a/src/domain/AppConfig.go b/src/domain/AppConfig.go index d71989b9..b85e14ec 100644 --- a/src/domain/AppConfig.go +++ b/src/domain/AppConfig.go @@ -29,6 +29,9 @@ type AppConfig struct { Port string `yaml:"port"` Host string `yaml:"host"` } `yaml:"httpServer"` + Network struct { + Interface string `yaml:"interface"` + } `yaml:"network"` Database struct { Entity DbConfig `yaml:"entity"` Log DbConfig `yaml:"log"` diff --git a/src/domain/Project.go b/src/domain/Project.go new file mode 100644 index 00000000..9d543819 --- /dev/null +++ b/src/domain/Project.go @@ -0,0 +1,18 @@ +package domain + +import "github.com/google/uuid" + +//Project entity of a project +type Project struct { + EntityUUID + //Name project name + Name string + //BridgeName name of a bridge that related to project + BridgeName string + //Subnet project subnet + Subnet string + //DHCPServerID project DHCP server ID + DHCPServerID uuid.UUID `gorm:"type:varchar(36);index"` + //TFTPServerID project TFTP server ID + TFTPServerID uuid.UUID `gorm:"type:varchar(36);index"` +} diff --git a/src/dtos/ProjectBaseDto.go b/src/dtos/ProjectBaseDto.go new file mode 100644 index 00000000..e49c55d7 --- /dev/null +++ b/src/dtos/ProjectBaseDto.go @@ -0,0 +1,6 @@ +package dtos + +type ProjectBaseDto struct { + Name string + Subnet string +} diff --git a/src/dtos/ProjectCreateDto.go b/src/dtos/ProjectCreateDto.go new file mode 100644 index 00000000..cb12b54d --- /dev/null +++ b/src/dtos/ProjectCreateDto.go @@ -0,0 +1,5 @@ +package dtos + +type ProjectCreateDto struct { + ProjectBaseDto +} diff --git a/src/dtos/ProjectDto.go b/src/dtos/ProjectDto.go new file mode 100644 index 00000000..e4b67e38 --- /dev/null +++ b/src/dtos/ProjectDto.go @@ -0,0 +1,11 @@ +package dtos + +import "github.com/google/uuid" + +type ProjectDto struct { + BaseDto[uuid.UUID] + ProjectBaseDto + BridgeName string + DHCPServerID uuid.UUID + TFTPServerID uuid.UUID +} diff --git a/src/infrastructure/GormDbInitializer.go b/src/infrastructure/GormDbInitializer.go index 2987ee80..51344e09 100644 --- a/src/infrastructure/GormDbInitializer.go +++ b/src/infrastructure/GormDbInitializer.go @@ -96,6 +96,7 @@ func NewGormEntityDb(cfg *domain.AppConfig) (*gorm.DB, error) { &domain.EthernetSwitch{}, &domain.EthernetSwitchPort{}, &domain.EthernetSwitchVLAN{}, + &domain.Project{}, &domain.DHCP4Config{}, &domain.DHCP4Lease{}, ) From fc9082988aa6c42f690f13fac76d36efc798d695 Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:28:47 +0300 Subject: [PATCH 2/7] src: app: added mappers for new entities Signed-off-by: Aleksandrov Dmitriy --- src/app/mappers/EntityDtoMapper.go | 6 ++++++ src/app/mappers/ProjectMapper.go | 24 ++++++++++++++++++++++++ src/domain/AppConfig.go | 1 + src/domain/Project.go | 1 + src/dtos/ProjectBaseDto.go | 6 +++++- src/dtos/ProjectCreateDto.go | 2 ++ src/dtos/ProjectDto.go | 7 ++++++- 7 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/app/mappers/ProjectMapper.go diff --git a/src/app/mappers/EntityDtoMapper.go b/src/app/mappers/EntityDtoMapper.go index 7ecea29d..6e60447e 100644 --- a/src/app/mappers/EntityDtoMapper.go +++ b/src/app/mappers/EntityDtoMapper.go @@ -56,6 +56,9 @@ func MapDtoToEntity(dto interface{}, entity interface{}) error { MapEthernetSwitchVLANCreateDto(dto.(dtos.EthernetSwitchVLANCreateDto), entity.(*domain.EthernetSwitchVLAN)) case dtos.EthernetSwitchVLANUpdateDto: MapEthernetSwitchVLANUpdateDto(dto.(dtos.EthernetSwitchVLANUpdateDto), entity.(*domain.EthernetSwitchVLAN)) + //Project + case dtos.ProjectCreateDto: + MapProjectCreateDtoToEntity(dto.(dtos.ProjectCreateDto), entity.(*domain.Project)) //DHCPServer case dtos.DHCP4ServerCreateDto: MapDHCP4ServerCreateDtoToEntity(dto.(dtos.DHCP4ServerCreateDto), entity.(*domain.DHCP4Config)) @@ -109,6 +112,9 @@ func MapEntityToDto(entity interface{}, dto interface{}) error { //EthernetSwitchVLAN case domain.EthernetSwitchVLAN: MapEthernetSwitchVLANToDto(entity.(domain.EthernetSwitchVLAN), dto.(*dtos.EthernetSwitchVLANDto)) + //Project + case domain.Project: + MapProjectToDto(entity.(domain.Project), dto.(*dtos.ProjectDto)) //DHCP4Server case domain.DHCP4Config: MapDHCP4ServerToDto(entity.(domain.DHCP4Config), dto.(*dtos.DHCP4ServerDto)) diff --git a/src/app/mappers/ProjectMapper.go b/src/app/mappers/ProjectMapper.go new file mode 100644 index 00000000..91956160 --- /dev/null +++ b/src/app/mappers/ProjectMapper.go @@ -0,0 +1,24 @@ +package mappers + +import ( + "rol/domain" + "rol/dtos" +) + +//MapProjectToDto map Project entity to dto +func MapProjectToDto(entity domain.Project, dto *dtos.ProjectDto) { + dto.ID = entity.ID + dto.Name = entity.Name + dto.Subnet = entity.Subnet + dto.BridgeName = entity.BridgeName + dto.CreatedAt = entity.CreatedAt + dto.UpdatedAt = entity.UpdatedAt + dto.DHCPServerID = entity.DHCPServerID + dto.TFTPServerID = entity.TFTPServerID +} + +//MapProjectCreateDtoToEntity map ProjectCreateDto dto to entity +func MapProjectCreateDtoToEntity(dto dtos.ProjectCreateDto, entity *domain.Project) { + entity.Name = dto.Name + entity.Subnet = dto.Subnet +} diff --git a/src/domain/AppConfig.go b/src/domain/AppConfig.go index b85e14ec..4a90466c 100644 --- a/src/domain/AppConfig.go +++ b/src/domain/AppConfig.go @@ -1,3 +1,4 @@ +// Package domain stores the main structures of the program package domain //MySQL structure with mysql db connection parameters diff --git a/src/domain/Project.go b/src/domain/Project.go index 9d543819..448ad3e6 100644 --- a/src/domain/Project.go +++ b/src/domain/Project.go @@ -1,3 +1,4 @@ +// Package domain stores the main structures of the program package domain import "github.com/google/uuid" diff --git a/src/dtos/ProjectBaseDto.go b/src/dtos/ProjectBaseDto.go index e49c55d7..e9e290df 100644 --- a/src/dtos/ProjectBaseDto.go +++ b/src/dtos/ProjectBaseDto.go @@ -1,6 +1,10 @@ +// Package dtos stores all data transfer objects package dtos +//ProjectBaseDto project base dto type ProjectBaseDto struct { - Name string + //Name project name + Name string + //Subnet project subnet xx.xx.xx.0 Subnet string } diff --git a/src/dtos/ProjectCreateDto.go b/src/dtos/ProjectCreateDto.go index cb12b54d..ee158937 100644 --- a/src/dtos/ProjectCreateDto.go +++ b/src/dtos/ProjectCreateDto.go @@ -1,5 +1,7 @@ +// Package dtos stores all data transfer objects package dtos +//ProjectCreateDto project create dto type ProjectCreateDto struct { ProjectBaseDto } diff --git a/src/dtos/ProjectDto.go b/src/dtos/ProjectDto.go index e4b67e38..a25f72ca 100644 --- a/src/dtos/ProjectDto.go +++ b/src/dtos/ProjectDto.go @@ -1,11 +1,16 @@ +// Package dtos stores all data transfer objects package dtos import "github.com/google/uuid" +//ProjectDto project dto type ProjectDto struct { BaseDto[uuid.UUID] ProjectBaseDto - BridgeName string + //BridgeName name of project bridge + BridgeName string + //DHCPServerID ip of project DHCP server DHCPServerID uuid.UUID + //TFTPServerID ip of project TFTP server TFTPServerID uuid.UUID } From cfaf0ee6f4e2e614d3a2f591837c20bd527b913e Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:29:06 +0300 Subject: [PATCH 3/7] src: added project management structs Signed-off-by: Aleksandrov Dmitriy --- src/app/services/ProjectService.go | 204 ++++++++++++++++++++ src/go.mod | 4 +- src/go.sum | 12 +- src/infrastructure/GormProjectRepository.go | 28 +++ 4 files changed, 239 insertions(+), 9 deletions(-) create mode 100644 src/app/services/ProjectService.go create mode 100644 src/infrastructure/GormProjectRepository.go diff --git a/src/app/services/ProjectService.go b/src/app/services/ProjectService.go new file mode 100644 index 00000000..62f9215f --- /dev/null +++ b/src/app/services/ProjectService.go @@ -0,0 +1,204 @@ +// Package services stores business logic for each entity +package services + +import ( + "context" + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "rol/app/errors" + "rol/app/interfaces" + "rol/app/mappers" + "rol/domain" + "rol/dtos" + "strings" +) + +//ProjectService is an object for create all project dependencies such as traffic rule and bridge +type ProjectService struct { + repository interfaces.IGenericRepository[uuid.UUID, domain.Project] + config *domain.AppConfig + dhcpService *DHCP4ServerService + tftpService *TFTPServerService + hostNetworkService *HostNetworkService + logger *logrus.Logger +} + +//NewProjectService ProjectService constructor +func NewProjectService(repo interfaces.IGenericRepository[uuid.UUID, domain.Project], DHCPService *DHCP4ServerService, + TFTPService *TFTPServerService, networkService *HostNetworkService, config *domain.AppConfig, log *logrus.Logger) *ProjectService { + return &ProjectService{ + repository: repo, + config: config, + dhcpService: DHCPService, + tftpService: TFTPService, + hostNetworkService: networkService, + logger: log, + } +} + +func (s ProjectService) createBridgeDto(createDto dtos.ProjectCreateDto) dtos.HostNetworkBridgeCreateDto { + bridgeIP := createDto.Subnet[:len(createDto.Subnet)-1] + "1/24" + return dtos.HostNetworkBridgeCreateDto{ + Name: createDto.Name, + HostNetworkBridgeBaseDto: dtos.HostNetworkBridgeBaseDto{ + Addresses: []string{bridgeIP}, + Slaves: []string{s.config.Network.Interface}, + }, + } +} + +func (s ProjectService) createDHCPDto(bridgeIP, bridgeName string) dtos.DHCP4ServerCreateDto { + ipLastDot := strings.LastIndex(bridgeIP, ".") + ipPart := bridgeIP[:ipLastDot] + return dtos.DHCP4ServerCreateDto{ + Range: ipPart + ".2-" + ipPart + ".254", + Mask: "255.255.255.0", + ServerID: bridgeIP, + Interface: bridgeName, + Gateway: bridgeIP, + DNS: "8.8.8.8;" + bridgeIP, + NTP: bridgeIP, + Enabled: true, + Port: 67, + LeaseTime: 3600, + } +} + +func (s ProjectService) createTFTPDto(bridgeIP string) dtos.TFTPServerCreateDto { + return dtos.TFTPServerCreateDto{TFTPServerBaseDto: dtos.TFTPServerBaseDto{ + Address: bridgeIP, + Port: "69", + Enabled: true, + }} +} + +func (s ProjectService) createTrafficRuleDto(createDto dtos.ProjectCreateDto) dtos.HostNetworkTrafficRuleCreateDto { + return dtos.HostNetworkTrafficRuleCreateDto{HostNetworkTrafficRuleBaseDto: dtos.HostNetworkTrafficRuleBaseDto{ + Chain: "POSTROUTING", + Action: "MASQUERADE", + Source: createDto.Subnet + "/24", + Destination: "", + }} +} + +//GetByID gets project by id +// +//Params: +// ctx - context is used only for logging +// id - project ID +//Return: +// dtos.ProjectDto - created project dto +// error - if an error occurs, otherwise nil +func (s ProjectService) GetByID(ctx context.Context, id uuid.UUID) (dtos.ProjectDto, error) { + return GetByID[dtos.ProjectDto](ctx, s.repository, id, nil) +} + +//GetList gets list of projects with search and pagination +// +//Params: +// ctx - context is used only for logging +// search - string for search in entity string fields +// orderBy - order by entity field name +// orderDirection - ascending or descending order +// page - page number +// pageSize - page size +//Return +// dtos.PaginatedItemsDto[dtos.ProjectDto] - paginated list of projects +// error - if an error occurs, otherwise nil +func (s ProjectService) GetList(ctx context.Context, search, orderBy, orderDirection string, page, pageSize int) (dtos.PaginatedItemsDto[dtos.ProjectDto], error) { + return GetList[dtos.ProjectDto](ctx, s.repository, search, orderBy, orderDirection, page, pageSize) +} + +//Create creates project and bridge with postrouting traffic rule for it +// +//Params: +// project - project entity +// projectSubnet - subnet for project +//Return: +// domain.Project - created project +// error - if an error occurs, otherwise nil +func (s ProjectService) Create(ctx context.Context, createDto dtos.ProjectCreateDto) (dtos.ProjectDto, error) { + bridgeDto := s.createBridgeDto(createDto) + bridge, err := s.hostNetworkService.CreateBridge(bridgeDto) + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "network service failed to create bridge") + } + bridgeIP := bridge.Addresses[0][:len(bridge.Addresses[0])-3] + dhcpDto := s.createDHCPDto(bridgeIP, bridge.Name) + dhcp, err := s.dhcpService.CreateServer(ctx, dhcpDto) + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "dhcp service failed to create server") + } + tftpDto := s.createTFTPDto(bridgeIP) + tftp, err := s.tftpService.CreateServer(ctx, tftpDto) + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "tftp service failed to create server") + } + trafficRuleDto := s.createTrafficRuleDto(createDto) + _, err = s.hostNetworkService.CreateTrafficRule("nat", trafficRuleDto) + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "network service failed to create traffic rule") + } + projectEntity := domain.Project{ + Name: createDto.Name, + BridgeName: bridge.Name, + Subnet: createDto.Subnet, + DHCPServerID: dhcp.ID, + TFTPServerID: tftp.ID, + } + newProject, err := s.repository.Insert(ctx, projectEntity) + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "repository failed to create project") + } + projectOutDto := &dtos.ProjectDto{} + err = mappers.MapEntityToDto(newProject, projectOutDto) + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "error map entity to dto") + } + err = s.hostNetworkService.Ping() + if err != nil { + return dtos.ProjectDto{}, errors.Internal.Wrap(err, "network service failed to save current configuration") + } + return *projectOutDto, nil +} + +//Delete project and its bridge with postrouting traffic rule +// +//Params: +// project - project entity +//Return: +// error - if an error occurs, otherwise nil +func (s ProjectService) Delete(ctx context.Context, id uuid.UUID) error { + project, err := s.GetByID(ctx, id) + if err != nil { + return err + } + err = s.dhcpService.DeleteServer(ctx, project.DHCPServerID) + if err != nil && !errors.As(err, errors.NotFound) { + return errors.Internal.Wrap(err, "dhcp service failed to delete server") + } + err = s.tftpService.DeleteServer(ctx, project.TFTPServerID) + if err != nil && !errors.As(err, errors.NotFound) { + return errors.Internal.Wrap(err, "tftp service failed to delete server") + } + trafficRule := dtos.HostNetworkTrafficRuleDeleteDto{HostNetworkTrafficRuleBaseDto: dtos.HostNetworkTrafficRuleBaseDto{ + Chain: "POSTROUTING", + Action: "MASQUERADE", + Source: project.Subnet + "/24", + Destination: "", + }} + err = s.hostNetworkService.DeleteTrafficRule("nat", trafficRule) + if err != nil && !errors.As(err, errors.NotFound) { + return errors.Internal.Wrap(err, "network service failed to delete traffic rule") + } + err = s.hostNetworkService.DeleteBridge(project.BridgeName) + if err != nil && !errors.As(err, errors.NotFound) { + return errors.Internal.Wrap(err, "network service failed to delete bridge") + } + err = s.hostNetworkService.Ping() + if err != nil { + return errors.Internal.Wrap(err, "network service failed to save current configuration") + } + + return s.repository.Delete(ctx, id) +} diff --git a/src/go.mod b/src/go.mod index b2683106..215356e2 100644 --- a/src/go.mod +++ b/src/go.mod @@ -14,7 +14,7 @@ require ( github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.1 - github.com/swaggo/swag v1.8.1 + github.com/swaggo/swag v1.8.6 github.com/vishvananda/netlink v1.1.0 go.uber.org/fx v1.17.1 gopkg.in/yaml.v3 v3.0.1 @@ -54,7 +54,7 @@ require ( github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect github.com/willf/bitset v1.1.11 // indirect - golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 // indirect + golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/tools v0.1.10 // indirect gopkg.in/ini.v1 v1.62.0 // indirect diff --git a/src/go.sum b/src/go.sum index 7a5846ef..d147d187 100644 --- a/src/go.sum +++ b/src/go.sum @@ -20,7 +20,6 @@ github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6Xge github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs= github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -272,7 +271,6 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= @@ -349,16 +347,16 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/swaggo/gin-swagger v1.4.2 h1:qDs1YrBOTnurDG/JVMc8678KhoS1B1okQGPtIqVz4YU= github.com/swaggo/gin-swagger v1.4.2/go.mod h1:hmJ1vPn+XjUvnbzjCdUAxVqgraxELxk8x5zAsjCE5mg= github.com/swaggo/swag v1.7.9/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU= -github.com/swaggo/swag v1.8.1 h1:JuARzFX1Z1njbCGz+ZytBR15TFJwF2Q7fu8puJHhQYI= -github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ= +github.com/swaggo/swag v1.8.6 h1:2rgOaLbonWu1PLP6G+/rYjSvPg0jQE0HtrEKuE380eg= +github.com/swaggo/swag v1.8.6/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/u-root/u-root v7.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY= github.com/u-root/uio v0.0.0-20210528114334-82958018845c h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA= @@ -463,8 +461,8 @@ golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA= -golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/src/infrastructure/GormProjectRepository.go b/src/infrastructure/GormProjectRepository.go new file mode 100644 index 00000000..158954ba --- /dev/null +++ b/src/infrastructure/GormProjectRepository.go @@ -0,0 +1,28 @@ +// Package infrastructure stores all implementations of app interfaces +package infrastructure + +import ( + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + "rol/app/interfaces" + "rol/domain" +) + +//GormProjectRepository repository for domain.Project entity +type GormProjectRepository struct { + *GormGenericRepository[uuid.UUID, domain.Project] +} + +//NewProjectRepository constructor for domain.Project GORM generic repository +//Params +// db - gorm database +// log - logrus logger +//Return +// generic.IGenericRepository[domain.Project] - new project repository +func NewProjectRepository(db *gorm.DB, log *logrus.Logger) interfaces.IGenericRepository[uuid.UUID, domain.Project] { + genericRepository := NewGormGenericRepository[uuid.UUID, domain.Project](db, log) + return GormProjectRepository{ + genericRepository, + } +} From 12908e3db013245cdf885d1bb3b48f646b9723d6 Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:29:25 +0300 Subject: [PATCH 4/7] src: webapi: added controllers for new entities Signed-off-by: Aleksandrov Dmitriy --- src/main.go | 2 + .../controllers/ProjectGinController.go | 156 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 src/webapi/controllers/ProjectGinController.go diff --git a/src/main.go b/src/main.go index a68ad769..e69e3f86 100644 --- a/src/main.go +++ b/src/main.go @@ -84,6 +84,8 @@ func main() { controllers.NewEthernetSwitchVLANGinController, controllers.NewDHCP4ServerGinController, controllers.NewTFTPServerGinController, + controllers.NewProjectGinController, + controllers.NewHostNetworkTrafficGinController, ), fx.Invoke( //Register logrus hooks diff --git a/src/webapi/controllers/ProjectGinController.go b/src/webapi/controllers/ProjectGinController.go new file mode 100644 index 00000000..3318f4f8 --- /dev/null +++ b/src/webapi/controllers/ProjectGinController.go @@ -0,0 +1,156 @@ +// Package controllers describes controllers for webapi +package controllers + +import ( + "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "rol/app/services" + "rol/dtos" + "rol/webapi" + "strconv" +) + +//ProjectGinController user project API controller +type ProjectGinController struct { + service *services.ProjectService + logger *logrus.Logger +} + +//NewProjectGinController user project controller constructor. Parameters pass through DI +// +//Params: +// projectService - user project service +// log - logrus logger +//Return: +// *ProjectGinController - instance of user project controller +func NewProjectGinController(projectService *services.ProjectService, log *logrus.Logger) *ProjectGinController { + return &ProjectGinController{ + service: projectService, + logger: log, + } +} + +//RegisterProjectGinController registers controller for getting user projects via api +func RegisterProjectGinController(controller *ProjectGinController, server *webapi.GinHTTPServer) { + groupRoute := server.Engine.Group("/api/v1") + + groupRoute.GET("/project/", controller.GetList) + groupRoute.GET("/project/:id", controller.GetByID) + groupRoute.POST("/project/", controller.Create) + groupRoute.DELETE("/project/:id", controller.Delete) +} + +//GetList get list of user projects +// +//Params: +// ctx - gin context +// +// @Summary Get list of user projects +// @version 1.0 +// @Tags project +// @Accept json +// @Produce json +// @param orderBy query string false "Order by field" +// @param orderDirection query string false "'asc' or 'desc' for ascending or descending order" +// @param search query string false "Searchable value in entity" +// @param page query int false "Page number" +// @param pageSize query int false "Number of entities per page" +// @Success 200 {object} dtos.PaginatedItemsDto[dtos.ProjectDto] +// @Failure 500 "Internal Server Error" +// @router /project/ [get] +func (p *ProjectGinController) GetList(ctx *gin.Context) { + orderBy := ctx.DefaultQuery("orderBy", "id") + orderDirection := ctx.DefaultQuery("orderDirection", "asc") + search := ctx.DefaultQuery("search", "") + page := ctx.DefaultQuery("page", "1") + pageInt, err := strconv.Atoi(page) + if err != nil { + pageInt = 1 + } + pageSize := ctx.DefaultQuery("pageSize", "10") + pageSizeInt, err := strconv.Atoi(pageSize) + if err != nil { + pageSizeInt = 10 + } + projList, err := p.service.GetList(ctx, search, orderBy, orderDirection, pageInt, pageSizeInt) + handleWithData(ctx, err, projList) +} + +//GetByID get user project by id +// +//Params: +// ctx - gin context +// +// @Summary Gets user project by id +// @version 1.0 +// @Tags project +// @Accept json +// @Produce json +// @param id path string true "User project ID" +// @Success 200 {object} dtos.ProjectDto +// @Failure 404 "Not Found" +// @Failure 500 "Internal Server Error" +// @router /project/{id} [get] +func (p *ProjectGinController) GetByID(ctx *gin.Context) { + strID := ctx.Param("id") + id, err := uuid.Parse(strID) + if err != nil { + abortWithStatusByErrorType(ctx, err) + return + } + vlan, err := p.service.GetByID(ctx, id) + handleWithData(ctx, err, vlan) +} + +//Create new user project +// +//Params: +// ctx - gin context +// +// @Summary Create new user project +// @version 1.0 +// @Tags project +// @Accept json +// @Produce json +// @Param request body dtos.ProjectCreateDto true "User project fields" +// @Success 200 {object} dtos.ProjectDto +// @Failure 400 {object} dtos.ValidationErrorDto +// @Failure 500 "Internal Server Error" +// @router /project/ [post] +func (p *ProjectGinController) Create(ctx *gin.Context) { + reqDto, err := getRequestDtoAndRestoreBody[dtos.ProjectCreateDto](ctx) + if err != nil { + abortWithStatusByErrorType(ctx, err) + return + } + + projectDto, err := p.service.Create(ctx, reqDto) + handleWithData(ctx, err, projectDto) +} + +//Delete user project +// +//Params: +// ctx - gin context +// +// @Summary Delete user project by id +// @version 1.0 +// @Tags project +// @Accept json +// @Produce json +// @param id path string true "User project ID" +// @Success 204 "OK, but No Content" +// @Failure 404 "Not Found" +// @Failure 500 "Internal Server Error" +// @router /project/{id} [delete] +func (p *ProjectGinController) Delete(ctx *gin.Context) { + strID := ctx.Param("id") + id, err := uuid.Parse(strID) + if err != nil { + abortWithStatusByErrorType(ctx, err) + return + } + err = p.service.Delete(ctx, id) + handle(ctx, err) +} From 1cf28b5e175f5879bf224abfd3cacb901bdab8a9 Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:30:20 +0300 Subject: [PATCH 5/7] src: added all new objects to DI container Signed-off-by: Aleksandrov Dmitriy --- src/main.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.go b/src/main.go index e69e3f86..66a38b03 100644 --- a/src/main.go +++ b/src/main.go @@ -62,6 +62,7 @@ func main() { infrastructure.NewGormDHCP4LeaseRepository, infrastructure.NewGormDHCP4ConfigRepository, infrastructure.NewCoreDHCP4ServerFactory, + infrastructure.NewProjectRepository, // Application logic services.NewEthernetSwitchService, services.NewHTTPLogService, @@ -70,6 +71,7 @@ func main() { services.NewHostNetworkService, services.NewDHCP4ServerService, services.NewTFTPServerService, + services.NewProjectService, // WEB API -> GIN Server webapi.NewGinHTTPServer, // WEB API -> GIN Controllers @@ -106,6 +108,8 @@ func main() { controllers.RegisterEthernetSwitchVLANGinController, controllers.RegisterDHCP4ServerGinController, controllers.RegisterTFTPServerGinController, + controllers.RegisterProjectGinController, + controllers.RegisterHostNetworkTrafficGinController, //Start GIN http server webapi.StartHTTPServer, ), From 37a2806fa4a024a59b7a32eb061ab0a36b61c4af Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:30:47 +0300 Subject: [PATCH 6/7] docs: added all related docs Signed-off-by: Aleksandrov Dmitriy --- .../controllers/ProjectController.puml | 40 +++ .../controllers/ProjectController.svg | 274 ++++++++++++++++++ docs/plantuml/dto/Project/ProjectBaseDto.puml | 11 + docs/plantuml/dto/Project/ProjectBaseDto.svg | 23 ++ .../dto/Project/ProjectCreateDto.puml | 12 + .../plantuml/dto/Project/ProjectCreateDto.svg | 47 +++ docs/plantuml/dto/Project/ProjectDto.puml | 17 ++ docs/plantuml/dto/Project/ProjectDto.svg | 69 +++++ docs/plantuml/entities/Project.puml | 20 ++ docs/plantuml/entities/Project.svg | 90 ++++++ .../repositories/GormProjectRepository.puml | 17 ++ .../repositories/GormProjectRepository.svg | 181 ++++++++++++ docs/plantuml/services/ProjectService.puml | 30 ++ docs/plantuml/services/ProjectService.svg | 223 ++++++++++++++ 14 files changed, 1054 insertions(+) create mode 100644 docs/plantuml/controllers/ProjectController.puml create mode 100644 docs/plantuml/controllers/ProjectController.svg create mode 100644 docs/plantuml/dto/Project/ProjectBaseDto.puml create mode 100644 docs/plantuml/dto/Project/ProjectBaseDto.svg create mode 100644 docs/plantuml/dto/Project/ProjectCreateDto.puml create mode 100644 docs/plantuml/dto/Project/ProjectCreateDto.svg create mode 100644 docs/plantuml/dto/Project/ProjectDto.puml create mode 100644 docs/plantuml/dto/Project/ProjectDto.svg create mode 100644 docs/plantuml/entities/Project.puml create mode 100644 docs/plantuml/entities/Project.svg create mode 100644 docs/plantuml/repositories/GormProjectRepository.puml create mode 100644 docs/plantuml/repositories/GormProjectRepository.svg create mode 100644 docs/plantuml/services/ProjectService.puml create mode 100644 docs/plantuml/services/ProjectService.svg diff --git a/docs/plantuml/controllers/ProjectController.puml b/docs/plantuml/controllers/ProjectController.puml new file mode 100644 index 00000000..4d1cb7b2 --- /dev/null +++ b/docs/plantuml/controllers/ProjectController.puml @@ -0,0 +1,40 @@ +@startuml + +!include ../services/ProjectService.puml + +package controllers { + class ProjectController { + -service *services.HostNetworkService + -- + -logger *logrus.Logger + -- + +GetList(ctx *gin.Context) + -- + +GetByID(ctx *gin.Context) + -- + +Create(ctx *gin.Context) + -- + +Delete(ctx *gin.Context) + } + + note left of ProjectController::GetList + Get list of user projects + end note + + note left of ProjectController::GetByID + Gets user project by id + end note + + note left of ProjectController::Create + Create new user project + end note + + note left of ProjectController::Delete + Delete user project by id + end note + + + UserProjectService -up- ProjectController::service +} + +@enduml diff --git a/docs/plantuml/controllers/ProjectController.svg b/docs/plantuml/controllers/ProjectController.svg new file mode 100644 index 00000000..9e184a50 --- /dev/null +++ b/docs/plantuml/controllers/ProjectController.svg @@ -0,0 +1,274 @@ +appdomaininfrastructurecontrollersIEntityModelIDTypeGetID() IDTypeGetCreatedAt() time.TimeGetUpdatedAt() *time.TimeGetDeletedAt() *time.TimeIGenericRepositoryIDType, interfaces.IEntityModel[IDType]GetList(ctx context.Context, orderBy string, orderDirection string, page int, size int, queryBuilder interfaces.IQueryBuilder) ([]EntityType, error)Count(ctx context.Context, queryBuilder interfaces.IQueryBuilder) (int, error)IsExist(ctx context.Context, id IDType, queryBuilder interfaces.IQueryBuilder) (bool, error)NewQueryBuilder(ctx context.Context) interfaces.IQueryBuilderGetById(ctx context.Context, id IDType) (EntityType, error)Update(ctx context.Context, entity EntityType) (EntityType, error)Insert(ctx context.Context, entity EntityType) (EntityType, error)Delete(ctx context.Context, id IDType) errorDeleteAll(ctx context.Context, queryBuilder interfaces.IQueryBuilder) errorDispose() errorGet list of elements with filtering and paginationGet count of entities with filteringChecks that entity with selected conditions is existedGet new instance of the query builderGet entity by ID from repositorySave the changes to the existing entity in the repositoryAdd entity to the repositoryDelete entity from repositoryDelete entities with selected conditionsDispose all allocated dataProjectServicerepository IGenericRepository<uuid.UUID, domain.Project>config *domain.AppConfigdhcpService *DHCP4ServerServicetftpService *TFTPServerServicehostNetworkService *HostNetworkServicelogger *logrus.LoggerGetList(ctx context.Context, search string, orderBy string, orderDirection string, page int, pageSize int) (PaginatedItemsDto[ProjectDto], error)GetByID(ctx context.Context, id uuid.UUID) (ProjectDto, error)Create(ctx context.Context, createDto ProjectCreateDto) (ProjectDto, error)Delete(ctx context.Context, id uuid.UUID) errorEntityUUIDEntityIDTypeID IDTypeCreatedAt time.TimeUpdatedAt *time.TimeDeletedAt gorm.DeletedAtProjectName stringBridgeName stringSubnet stringDHCPServerID uuid.UUIDTFTPServerID uuid.UUIDGormGenericRepositoryIDType, EntityTypeGormProjectRepositoryEntityType is ProjectProjectControllerservice *services.HostNetworkServicelogger *logrus.LoggerGetList(ctx *gin.Context)GetByID(ctx *gin.Context)Create(ctx *gin.Context)Delete(ctx *gin.Context)Get list of user projectsGets user project by idCreate new user projectDelete user project by idUserProjectServiceIDType is uuid.UUID \ No newline at end of file diff --git a/docs/plantuml/dto/Project/ProjectBaseDto.puml b/docs/plantuml/dto/Project/ProjectBaseDto.puml new file mode 100644 index 00000000..5526b36b --- /dev/null +++ b/docs/plantuml/dto/Project/ProjectBaseDto.puml @@ -0,0 +1,11 @@ +@startuml + +package dtos { + class ProjectBaseDto { + +Name string + -- + +Subnet string + } +} + +@enduml \ No newline at end of file diff --git a/docs/plantuml/dto/Project/ProjectBaseDto.svg b/docs/plantuml/dto/Project/ProjectBaseDto.svg new file mode 100644 index 00000000..53a6a222 --- /dev/null +++ b/docs/plantuml/dto/Project/ProjectBaseDto.svg @@ -0,0 +1,23 @@ +dtosProjectBaseDtoName stringSubnet string \ No newline at end of file diff --git a/docs/plantuml/dto/Project/ProjectCreateDto.puml b/docs/plantuml/dto/Project/ProjectCreateDto.puml new file mode 100644 index 00000000..bc9eafb0 --- /dev/null +++ b/docs/plantuml/dto/Project/ProjectCreateDto.puml @@ -0,0 +1,12 @@ +@startuml + +!include ProjectBaseDto.puml + +package dtos { + class ProjectCreateDto + + ProjectCreateDto --* ProjectBaseDto +} + + +@enduml \ No newline at end of file diff --git a/docs/plantuml/dto/Project/ProjectCreateDto.svg b/docs/plantuml/dto/Project/ProjectCreateDto.svg new file mode 100644 index 00000000..0fd71647 --- /dev/null +++ b/docs/plantuml/dto/Project/ProjectCreateDto.svg @@ -0,0 +1,47 @@ +dtosProjectBaseDtoName stringSubnet stringProjectCreateDto \ No newline at end of file diff --git a/docs/plantuml/dto/Project/ProjectDto.puml b/docs/plantuml/dto/Project/ProjectDto.puml new file mode 100644 index 00000000..20b394ad --- /dev/null +++ b/docs/plantuml/dto/Project/ProjectDto.puml @@ -0,0 +1,17 @@ +@startuml +!include ProjectBaseDto.puml +!include ../BaseDto.puml + +package dtos { + class ProjectDto { + +BridgeName string + -- + +DHCPServerID uuid.UUID + -- + +TFTPServerID uuid.UUID + } + ProjectDto --* ProjectBaseDto + ProjectDto --* BaseDto +} + +@enduml \ No newline at end of file diff --git a/docs/plantuml/dto/Project/ProjectDto.svg b/docs/plantuml/dto/Project/ProjectDto.svg new file mode 100644 index 00000000..9a5036b6 --- /dev/null +++ b/docs/plantuml/dto/Project/ProjectDto.svg @@ -0,0 +1,69 @@ +dtosProjectBaseDtoName stringSubnet stringBaseDtoIDTypeID IDTypeCreatedAt time.TimeUpdatedAt time.TimeProjectDtoBridgeName stringDHCPServerID uuid.UUIDTFTPServerID uuid.UUID \ No newline at end of file diff --git a/docs/plantuml/entities/Project.puml b/docs/plantuml/entities/Project.puml new file mode 100644 index 00000000..ed3591c7 --- /dev/null +++ b/docs/plantuml/entities/Project.puml @@ -0,0 +1,20 @@ +@startuml Project + +!include Entity.puml + +package domain { + class Project { + +Name string + -- + +BridgeName string + -- + +Subnet string + -- + +DHCPServerID uuid.UUID + -- + +TFTPServerID uuid.UUID + } + Project -down-* EntityUUID +} + +@enduml diff --git a/docs/plantuml/entities/Project.svg b/docs/plantuml/entities/Project.svg new file mode 100644 index 00000000..a74c42cf --- /dev/null +++ b/docs/plantuml/entities/Project.svg @@ -0,0 +1,90 @@ +appdomainIEntityModelIDTypeGetID() IDTypeGetCreatedAt() time.TimeGetUpdatedAt() *time.TimeGetDeletedAt() *time.TimeEntityUUIDEntityIDTypeID IDTypeCreatedAt time.TimeUpdatedAt *time.TimeDeletedAt gorm.DeletedAtProjectName stringBridgeName stringSubnet stringDHCPServerID uuid.UUIDTFTPServerID uuid.UUIDIDType is uuid.UUID \ No newline at end of file diff --git a/docs/plantuml/repositories/GormProjectRepository.puml b/docs/plantuml/repositories/GormProjectRepository.puml new file mode 100644 index 00000000..90460143 --- /dev/null +++ b/docs/plantuml/repositories/GormProjectRepository.puml @@ -0,0 +1,17 @@ +@startuml +!include ../entities/Project.puml +!include GormGenericRepository.puml + +package infrastructure { + class GormProjectRepository + + GormProjectRepository -down-* GormGenericRepository + + + note "EntityType is Project" as ProjectTypeNote + + GormProjectRepository .down. ProjectTypeNote + GormGenericRepository <.up. ProjectTypeNote + Project .. ProjectTypeNote +} +@enduml \ No newline at end of file diff --git a/docs/plantuml/repositories/GormProjectRepository.svg b/docs/plantuml/repositories/GormProjectRepository.svg new file mode 100644 index 00000000..a30938eb --- /dev/null +++ b/docs/plantuml/repositories/GormProjectRepository.svg @@ -0,0 +1,181 @@ +appdomaininfrastructureIEntityModelIDTypeGetID() IDTypeGetCreatedAt() time.TimeGetUpdatedAt() *time.TimeGetDeletedAt() *time.TimeIGenericRepositoryIDType, interfaces.IEntityModel[IDType]GetList(ctx context.Context, orderBy string, orderDirection string, page int, size int, queryBuilder interfaces.IQueryBuilder) ([]EntityType, error)Count(ctx context.Context, queryBuilder interfaces.IQueryBuilder) (int, error)IsExist(ctx context.Context, id IDType, queryBuilder interfaces.IQueryBuilder) (bool, error)NewQueryBuilder(ctx context.Context) interfaces.IQueryBuilderGetById(ctx context.Context, id IDType) (EntityType, error)Update(ctx context.Context, entity EntityType) (EntityType, error)Insert(ctx context.Context, entity EntityType) (EntityType, error)Delete(ctx context.Context, id IDType) errorDeleteAll(ctx context.Context, queryBuilder interfaces.IQueryBuilder) errorDispose() errorGet list of elements with filtering and paginationGet count of entities with filteringChecks that entity with selected conditions is existedGet new instance of the query builderGet entity by ID from repositorySave the changes to the existing entity in the repositoryAdd entity to the repositoryDelete entity from repositoryDelete entities with selected conditionsDispose all allocated dataEntityUUIDEntityIDTypeID IDTypeCreatedAt time.TimeUpdatedAt *time.TimeDeletedAt gorm.DeletedAtProjectName stringBridgeName stringSubnet stringDHCPServerID uuid.UUIDTFTPServerID uuid.UUIDGormGenericRepositoryIDType, EntityTypeGormProjectRepositoryEntityType is ProjectIDType is uuid.UUID \ No newline at end of file diff --git a/docs/plantuml/services/ProjectService.puml b/docs/plantuml/services/ProjectService.puml new file mode 100644 index 00000000..81e29be1 --- /dev/null +++ b/docs/plantuml/services/ProjectService.puml @@ -0,0 +1,30 @@ +@startuml + +!include ../repositories/GormProjectRepository.puml + +package app { + class ProjectService { + -repository IGenericRepository + -- + -config *domain.AppConfig + -- + -dhcpService *DHCP4ServerService + -- + -tftpService *TFTPServerService + -- + -hostNetworkService *HostNetworkService + -- + -logger *logrus.Logger + -- + +GetList(ctx context.Context, search string, orderBy string, orderDirection string, page int, pageSize int) (PaginatedItemsDto[ProjectDto], error) + -- + +GetByID(ctx context.Context, id uuid.UUID) (ProjectDto, error) + -- + +Create(ctx context.Context, createDto ProjectCreateDto) (ProjectDto, error) + -- + +Delete(ctx context.Context, id uuid.UUID) error + } + + GormProjectRepository -- ProjectService::repository +} +@enduml \ No newline at end of file diff --git a/docs/plantuml/services/ProjectService.svg b/docs/plantuml/services/ProjectService.svg new file mode 100644 index 00000000..5d7b7d84 --- /dev/null +++ b/docs/plantuml/services/ProjectService.svg @@ -0,0 +1,223 @@ +appdomaininfrastructureIEntityModelIDTypeGetID() IDTypeGetCreatedAt() time.TimeGetUpdatedAt() *time.TimeGetDeletedAt() *time.TimeIGenericRepositoryIDType, interfaces.IEntityModel[IDType]GetList(ctx context.Context, orderBy string, orderDirection string, page int, size int, queryBuilder interfaces.IQueryBuilder) ([]EntityType, error)Count(ctx context.Context, queryBuilder interfaces.IQueryBuilder) (int, error)IsExist(ctx context.Context, id IDType, queryBuilder interfaces.IQueryBuilder) (bool, error)NewQueryBuilder(ctx context.Context) interfaces.IQueryBuilderGetById(ctx context.Context, id IDType) (EntityType, error)Update(ctx context.Context, entity EntityType) (EntityType, error)Insert(ctx context.Context, entity EntityType) (EntityType, error)Delete(ctx context.Context, id IDType) errorDeleteAll(ctx context.Context, queryBuilder interfaces.IQueryBuilder) errorDispose() errorGet list of elements with filtering and paginationGet count of entities with filteringChecks that entity with selected conditions is existedGet new instance of the query builderGet entity by ID from repositorySave the changes to the existing entity in the repositoryAdd entity to the repositoryDelete entity from repositoryDelete entities with selected conditionsDispose all allocated dataProjectServicerepository IGenericRepository<uuid.UUID, domain.Project>config *domain.AppConfigdhcpService *DHCP4ServerServicetftpService *TFTPServerServicehostNetworkService *HostNetworkServicelogger *logrus.LoggerGetList(ctx context.Context, search string, orderBy string, orderDirection string, page int, pageSize int) (PaginatedItemsDto[ProjectDto], error)GetByID(ctx context.Context, id uuid.UUID) (ProjectDto, error)Create(ctx context.Context, createDto ProjectCreateDto) (ProjectDto, error)Delete(ctx context.Context, id uuid.UUID) errorEntityUUIDEntityIDTypeID IDTypeCreatedAt time.TimeUpdatedAt *time.TimeDeletedAt gorm.DeletedAtProjectName stringBridgeName stringSubnet stringDHCPServerID uuid.UUIDTFTPServerID uuid.UUIDGormGenericRepositoryIDType, EntityTypeGormProjectRepositoryEntityType is ProjectIDType is uuid.UUID \ No newline at end of file From 7f65cf6e0b40058b546113b08d057347efb003d2 Mon Sep 17 00:00:00 2001 From: Aleksandrov Dmitriy Date: Thu, 15 Dec 2022 12:31:02 +0300 Subject: [PATCH 7/7] src: webapi: swagger: updated swagger documentation Signed-off-by: Aleksandrov Dmitriy --- src/webapi/swagger/docs.go | 232 ++++++++++++++++++++++++++++++++ src/webapi/swagger/swagger.json | 232 ++++++++++++++++++++++++++++++++ src/webapi/swagger/swagger.yaml | 155 +++++++++++++++++++++ 3 files changed, 619 insertions(+) diff --git a/src/webapi/swagger/docs.go b/src/webapi/swagger/docs.go index 0832277c..45f1229f 100644 --- a/src/webapi/swagger/docs.go +++ b/src/webapi/swagger/docs.go @@ -1943,6 +1943,172 @@ const docTemplate = `{ } } }, + "/project/": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Get list of user projects", + "parameters": [ + { + "type": "string", + "description": "Order by field", + "name": "orderBy", + "in": "query" + }, + { + "type": "string", + "description": "'asc' or 'desc' for ascending or descending order", + "name": "orderDirection", + "in": "query" + }, + { + "type": "string", + "description": "Searchable value in entity", + "name": "search", + "in": "query" + }, + { + "type": "integer", + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Number of entities per page", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dtos.PaginatedItemsDto-dtos_ProjectDto" + } + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Create new user project", + "parameters": [ + { + "description": "User project fields", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dtos.ProjectCreateDto" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dtos.ProjectDto" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/dtos.ValidationErrorDto" + } + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/project/{id}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Gets user project by id", + "parameters": [ + { + "type": "string", + "description": "User project ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dtos.ProjectDto" + } + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Delete user project by id", + "parameters": [ + { + "type": "string", + "description": "User project ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "OK, but No Content" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, "/template/device/": { "get": { "consumes": [ @@ -3410,6 +3576,22 @@ const docTemplate = `{ } } }, + "dtos.PaginatedItemsDto-dtos_ProjectDto": { + "type": "object", + "properties": { + "items": { + "description": "Items slice of items", + "type": "array", + "items": { + "$ref": "#/definitions/dtos.ProjectDto" + } + }, + "pagination": { + "description": "Pagination info about pagination", + "$ref": "#/definitions/dtos.PaginationInfoDto" + } + } + }, "dtos.PaginatedItemsDto-dtos_TFTPPathDto": { "type": "object", "properties": { @@ -3463,6 +3645,56 @@ const docTemplate = `{ } } }, + "dtos.ProjectCreateDto": { + "type": "object", + "properties": { + "name": { + "description": "Name project name", + "type": "string" + }, + "subnet": { + "description": "Subnet project subnet xx.xx.xx.0", + "type": "string" + } + } + }, + "dtos.ProjectDto": { + "type": "object", + "properties": { + "bridgeName": { + "description": "BridgeName name of project bridge", + "type": "string" + }, + "createdAt": { + "description": "CreatedAt - entity create time", + "type": "string" + }, + "dhcpserverID": { + "description": "DHCPServerID ip of project DHCP server", + "type": "string" + }, + "id": { + "description": "ID - unique identifier", + "type": "string" + }, + "name": { + "description": "Name project name", + "type": "string" + }, + "subnet": { + "description": "Subnet project subnet xx.xx.xx.0", + "type": "string" + }, + "tftpserverID": { + "description": "TFTPServerID ip of project TFTP server", + "type": "string" + }, + "updatedAt": { + "description": "UpdatedAt - entity update time", + "type": "string" + } + } + }, "dtos.TFTPPathCreateDto": { "type": "object", "properties": { diff --git a/src/webapi/swagger/swagger.json b/src/webapi/swagger/swagger.json index f8cd8caf..2d27193a 100644 --- a/src/webapi/swagger/swagger.json +++ b/src/webapi/swagger/swagger.json @@ -1936,6 +1936,172 @@ } } }, + "/project/": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Get list of user projects", + "parameters": [ + { + "type": "string", + "description": "Order by field", + "name": "orderBy", + "in": "query" + }, + { + "type": "string", + "description": "'asc' or 'desc' for ascending or descending order", + "name": "orderDirection", + "in": "query" + }, + { + "type": "string", + "description": "Searchable value in entity", + "name": "search", + "in": "query" + }, + { + "type": "integer", + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Number of entities per page", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dtos.PaginatedItemsDto-dtos_ProjectDto" + } + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Create new user project", + "parameters": [ + { + "description": "User project fields", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dtos.ProjectCreateDto" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dtos.ProjectDto" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/dtos.ValidationErrorDto" + } + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/project/{id}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Gets user project by id", + "parameters": [ + { + "type": "string", + "description": "User project ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/dtos.ProjectDto" + } + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "project" + ], + "summary": "Delete user project by id", + "parameters": [ + { + "type": "string", + "description": "User project ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "OK, but No Content" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, "/template/device/": { "get": { "consumes": [ @@ -3403,6 +3569,22 @@ } } }, + "dtos.PaginatedItemsDto-dtos_ProjectDto": { + "type": "object", + "properties": { + "items": { + "description": "Items slice of items", + "type": "array", + "items": { + "$ref": "#/definitions/dtos.ProjectDto" + } + }, + "pagination": { + "description": "Pagination info about pagination", + "$ref": "#/definitions/dtos.PaginationInfoDto" + } + } + }, "dtos.PaginatedItemsDto-dtos_TFTPPathDto": { "type": "object", "properties": { @@ -3456,6 +3638,56 @@ } } }, + "dtos.ProjectCreateDto": { + "type": "object", + "properties": { + "name": { + "description": "Name project name", + "type": "string" + }, + "subnet": { + "description": "Subnet project subnet xx.xx.xx.0", + "type": "string" + } + } + }, + "dtos.ProjectDto": { + "type": "object", + "properties": { + "bridgeName": { + "description": "BridgeName name of project bridge", + "type": "string" + }, + "createdAt": { + "description": "CreatedAt - entity create time", + "type": "string" + }, + "dhcpserverID": { + "description": "DHCPServerID ip of project DHCP server", + "type": "string" + }, + "id": { + "description": "ID - unique identifier", + "type": "string" + }, + "name": { + "description": "Name project name", + "type": "string" + }, + "subnet": { + "description": "Subnet project subnet xx.xx.xx.0", + "type": "string" + }, + "tftpserverID": { + "description": "TFTPServerID ip of project TFTP server", + "type": "string" + }, + "updatedAt": { + "description": "UpdatedAt - entity update time", + "type": "string" + } + } + }, "dtos.TFTPPathCreateDto": { "type": "object", "properties": { diff --git a/src/webapi/swagger/swagger.yaml b/src/webapi/swagger/swagger.yaml index 94d7aae0..5247d42f 100644 --- a/src/webapi/swagger/swagger.yaml +++ b/src/webapi/swagger/swagger.yaml @@ -734,6 +734,17 @@ definitions: $ref: '#/definitions/dtos.PaginationInfoDto' description: Pagination info about pagination type: object + dtos.PaginatedItemsDto-dtos_ProjectDto: + properties: + items: + description: Items slice of items + items: + $ref: '#/definitions/dtos.ProjectDto' + type: array + pagination: + $ref: '#/definitions/dtos.PaginationInfoDto' + description: Pagination info about pagination + type: object dtos.PaginatedItemsDto-dtos_TFTPPathDto: properties: items: @@ -771,6 +782,42 @@ definitions: description: TotalPages - total number of pages type: integer type: object + dtos.ProjectCreateDto: + properties: + name: + description: Name project name + type: string + subnet: + description: Subnet project subnet xx.xx.xx.0 + type: string + type: object + dtos.ProjectDto: + properties: + bridgeName: + description: BridgeName name of project bridge + type: string + createdAt: + description: CreatedAt - entity create time + type: string + dhcpserverID: + description: DHCPServerID ip of project DHCP server + type: string + id: + description: ID - unique identifier + type: string + name: + description: Name project name + type: string + subnet: + description: Subnet project subnet xx.xx.xx.0 + type: string + tftpserverID: + description: TFTPServerID ip of project TFTP server + type: string + updatedAt: + description: UpdatedAt - entity update time + type: string + type: object dtos.TFTPPathCreateDto: properties: actualPath: @@ -2141,6 +2188,114 @@ paths: summary: Gets http log by id tags: - log + /project/: + get: + consumes: + - application/json + parameters: + - description: Order by field + in: query + name: orderBy + type: string + - description: '''asc'' or ''desc'' for ascending or descending order' + in: query + name: orderDirection + type: string + - description: Searchable value in entity + in: query + name: search + type: string + - description: Page number + in: query + name: page + type: integer + - description: Number of entities per page + in: query + name: pageSize + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dtos.PaginatedItemsDto-dtos_ProjectDto' + "500": + description: Internal Server Error + summary: Get list of user projects + tags: + - project + post: + consumes: + - application/json + parameters: + - description: User project fields + in: body + name: request + required: true + schema: + $ref: '#/definitions/dtos.ProjectCreateDto' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dtos.ProjectDto' + "400": + description: Bad Request + schema: + $ref: '#/definitions/dtos.ValidationErrorDto' + "500": + description: Internal Server Error + summary: Create new user project + tags: + - project + /project/{id}: + delete: + consumes: + - application/json + parameters: + - description: User project ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: OK, but No Content + "404": + description: Not Found + "500": + description: Internal Server Error + summary: Delete user project by id + tags: + - project + get: + consumes: + - application/json + parameters: + - description: User project ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/dtos.ProjectDto' + "404": + description: Not Found + "500": + description: Internal Server Error + summary: Gets user project by id + tags: + - project /template/device/: get: consumes: