package orchestrator import ( "context" "net" "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/orchestrator/extensions" "github.com/gravitl/netmaker/schema" "github.com/gravitl/netmaker/scope" testutils "github.com/gravitl/netmaker/test/utils" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "gorm.io/datatypes" ) type CENodeOrchestratorTestSuite struct { ctx context.Context suite.Suite db string } func NewSqliteCENodeOrchestratorTestSuite() *CENodeOrchestratorTestSuite { return &CENodeOrchestratorTestSuite{ db: "sqlite", } } func NewPostgresCENodeOrchestratorTestSuite() *CENodeOrchestratorTestSuite { return &CENodeOrchestratorTestSuite{ db: "postgres", } } func (c *CENodeOrchestratorTestSuite) SetupSuite() { switch c.db { case "postgres": testutils.InitPostgres(c.T()) default: testutils.InitSqlite(c.T()) } InitializeRepository(extensions.NewCEFactory()) testutils.CreateDefaultOrgAndTenant(c.T(), db.WithContext(c.T().Context())) defaultTenant := &schema.Tenant{} err := defaultTenant.GetDefault(db.WithContext(c.T().Context())) require.NoError(c.T(), err) c.ctx = scope.WithContext(db.WithContext(c.T().Context()), scope.TenantScope, defaultTenant.ID) } func (c *CENodeOrchestratorTestSuite) TearDownSuite() { switch c.db { case "postgres": testutils.CleanupPostgres(c.T()) default: testutils.CleanupSqlite(c.T()) } } func (c *CENodeOrchestratorTestSuite) TestCreateNode() { host := testutils.CreateHost(c.T(), c.ctx, "host-0") networkIPv4 := testutils.CreateIPv4Network(c.T(), c.ctx, "network-ipv4") networkIPv6 := testutils.CreateIPv6Network(c.T(), c.ctx, "network-ipv6") networkIPv10 := testutils.CreateIPv10Network(c.T(), c.ctx, "network-ipv10") c.Run("IPv4 Network", func() { node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, networkIPv4) c.Require().NoError(err) c.Require().Equal(host.ID.String(), node.HostID) c.Require().NotNil(node.Host) c.Require().Equal(networkIPv4.ID, node.NetworkID) c.Require().NotNil(node.Network) c.Require().True(node.Connected) c.Require().NotEmpty(node.Address) _, _, err = net.ParseCIDR(node.Address) c.Require().NoError(err) c.Require().Empty(node.Address6) c.Require().Contains(host.Nodes, node.ID) testutils.DeleteNode(c.T(), c.ctx, node) }) c.Run("IPv6 Network", func() { node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, networkIPv6) c.Require().NoError(err) c.Require().Equal(host.ID.String(), node.HostID) c.Require().NotNil(node.Host) c.Require().Equal(networkIPv6.ID, node.NetworkID) c.Require().NotNil(node.Network) c.Require().True(node.Connected) c.Require().Empty(node.Address) c.Require().NotEmpty(node.Address6) _, _, err = net.ParseCIDR(node.Address6) c.Require().NoError(err) c.Require().Contains(host.Nodes, node.ID) testutils.DeleteNode(c.T(), c.ctx, node) }) c.Run("IPv10 Network", func() { node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, networkIPv10) c.Require().NoError(err) c.Require().Equal(host.ID.String(), node.HostID) c.Require().NotNil(node.Host) c.Require().Equal(networkIPv10.ID, node.NetworkID) c.Require().NotNil(node.Network) c.Require().True(node.Connected) c.Require().NotEmpty(node.Address) _, _, err = net.ParseCIDR(node.Address) c.Require().NoError(err) c.Require().NotEmpty(node.Address6) _, _, err = net.ParseCIDR(node.Address6) c.Require().NoError(err) c.Require().Contains(host.Nodes, node.ID) testutils.DeleteNode(c.T(), c.ctx, node) }) testutils.DeleteNetwork(c.T(), c.ctx, networkIPv4) testutils.DeleteNetwork(c.T(), c.ctx, networkIPv6) testutils.DeleteNetwork(c.T(), c.ctx, networkIPv10) testutils.DeleteHost(c.T(), c.ctx, host) } func (c *CENodeOrchestratorTestSuite) TestCreateNodeWithDefaultHost() { network := testutils.CreateIPv10Network(c.T(), c.ctx, "network-0") c.Run("Linux", func() { host := testutils.CreateHost(c.T(), c.ctx, "host-0") host.OS = "linux" host.IsDefault = true err := host.Upsert(c.ctx) c.Require().NoError(err) node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network) c.Require().NoError(err) c.Require().True(node.IsGateway) c.Require().False(node.IsInternetGateway) c.Require().Equal("no", node.IsAutoRelay) c.Require().Empty(node.RelayedClients) c.Require().Empty(node.RelayedIGWClients) c.Require().Equal(datatypes.NewJSONType(map[string]string{}), node.AutoRelayedPeers) testutils.DeleteNode(c.T(), c.ctx, node) testutils.DeleteHost(c.T(), c.ctx, host) }) c.Run("Windows", func() { host := testutils.CreateHost(c.T(), c.ctx, "host-0") host.OS = "windows" host.IsDefault = true err := host.Upsert(c.ctx) c.Require().NoError(err) node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network) c.Require().NoError(err) c.Require().True(node.IsGateway) testutils.DeleteNode(c.T(), c.ctx, node) testutils.DeleteHost(c.T(), c.ctx, host) }) c.Run("Darwin", func() { host := testutils.CreateHost(c.T(), c.ctx, "host-0") host.OS = "darwin" host.IsDefault = true err := host.Upsert(c.ctx) c.Require().NoError(err) _, err = GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network) c.Require().ErrorContains(err, "gateway can only be created on linux or windows based node") testutils.DeleteHost(c.T(), c.ctx, host) }) testutils.DeleteNetwork(c.T(), c.ctx, network) } func (c *CENodeOrchestratorTestSuite) TestCreateNodeWithEnrollmentKey() { host := testutils.CreateHost(c.T(), c.ctx, "host-0") network := testutils.CreateIPv10Network(c.T(), c.ctx, "network-0") c.Run("With AutoAssignGateway", func() { key := &schema.EnrollmentKey{ AutoAssignGateway: true, } node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network, UseKey(key)) c.Require().NoError(err) c.Require().False(node.AutoAssignGateway) testutils.DeleteNode(c.T(), c.ctx, node) }) c.Run("Without AutoAssignGateway", func() { key := &schema.EnrollmentKey{ AutoAssignGateway: false, } node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network, UseKey(key)) c.Require().NoError(err) c.Require().False(node.AutoAssignGateway) testutils.DeleteNode(c.T(), c.ctx, node) }) c.Run("With Tags", func() { key := &schema.EnrollmentKey{ Tags: []string{"tag-0"}, } node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network, UseKey(key)) c.Require().NoError(err) c.Require().NotContains(node.Tags, key.Tags[0]) testutils.DeleteNode(c.T(), c.ctx, node) }) c.Run("Without Tags", func() { key := &schema.EnrollmentKey{ Tags: []string{}, } node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network, UseKey(key)) c.Require().NoError(err) c.Require().Empty(node.Tags) testutils.DeleteNode(c.T(), c.ctx, node) }) c.Run("With Gateway", func() { gatewayHost := testutils.CreateHost(c.T(), c.ctx, "gateway-0") gatewayHost.OS = "linux" gatewayHost.IsDefault = true gateway, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, gatewayHost, network) c.Require().NoError(err) key := &schema.EnrollmentKey{ GatewayID: &gateway.ID, } node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network, UseKey(key)) c.Require().NoError(err) c.Require().NotNil(node.RelayedByNodeID) c.Require().Equal(gateway.ID, *node.RelayedByNodeID) err = gateway.Get(c.ctx) c.Require().NoError(err) c.Require().Contains(gateway.RelayedClients, node.ID) testutils.DeleteNode(c.T(), c.ctx, node) testutils.DeleteNode(c.T(), c.ctx, gateway) testutils.DeleteHost(c.T(), c.ctx, gatewayHost) }) c.Run("Without Gateway", func() { key := &schema.EnrollmentKey{} node, err := GetRepository().NodeOrchestrator().CreateNode(c.ctx, host, network, UseKey(key)) c.Require().NoError(err) testutils.DeleteNode(c.T(), c.ctx, node) }) testutils.DeleteNetwork(c.T(), c.ctx, network) testutils.DeleteHost(c.T(), c.ctx, host) }