Remove Account.Rules from Store engines (#1528)

This commit is contained in:
Yury Gargay 2024-02-19 17:17:36 +01:00 committed by GitHub
parent cb3408a10b
commit db3cba5e0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 106 additions and 156 deletions

View File

@ -209,8 +209,6 @@ type Account struct {
UsersG []User `json:"-" gorm:"foreignKey:AccountID;references:id"` UsersG []User `json:"-" gorm:"foreignKey:AccountID;references:id"`
Groups map[string]*Group `gorm:"-"` Groups map[string]*Group `gorm:"-"`
GroupsG []Group `json:"-" gorm:"foreignKey:AccountID;references:id"` GroupsG []Group `json:"-" gorm:"foreignKey:AccountID;references:id"`
Rules map[string]*Rule `gorm:"-"`
RulesG []Rule `json:"-" gorm:"foreignKey:AccountID;references:id"`
Policies []*Policy `gorm:"foreignKey:AccountID;references:id"` Policies []*Policy `gorm:"foreignKey:AccountID;references:id"`
Routes map[string]*route.Route `gorm:"-"` Routes map[string]*route.Route `gorm:"-"`
RoutesG []route.Route `json:"-" gorm:"foreignKey:AccountID;references:id"` RoutesG []route.Route `json:"-" gorm:"foreignKey:AccountID;references:id"`
@ -219,6 +217,9 @@ type Account struct {
DNSSettings DNSSettings `gorm:"embedded;embeddedPrefix:dns_settings_"` DNSSettings DNSSettings `gorm:"embedded;embeddedPrefix:dns_settings_"`
// Settings is a dictionary of Account settings // Settings is a dictionary of Account settings
Settings *Settings `gorm:"embedded;embeddedPrefix:settings_"` Settings *Settings `gorm:"embedded;embeddedPrefix:settings_"`
// deprecated on store and api level
Rules map[string]*Rule `json:"-" gorm:"-"`
RulesG []Rule `json:"-" gorm:"-"`
} }
type UserInfo struct { type UserInfo struct {
@ -635,11 +636,6 @@ func (a *Account) Copy() *Account {
groups[id] = group.Copy() groups[id] = group.Copy()
} }
rules := map[string]*Rule{}
for id, rule := range a.Rules {
rules[id] = rule.Copy()
}
policies := []*Policy{} policies := []*Policy{}
for _, policy := range a.Policies { for _, policy := range a.Policies {
policies = append(policies, policy.Copy()) policies = append(policies, policy.Copy())
@ -673,7 +669,6 @@ func (a *Account) Copy() *Account {
Peers: peers, Peers: peers,
Users: users, Users: users,
Groups: groups, Groups: groups,
Rules: rules,
Policies: policies, Policies: policies,
Routes: routes, Routes: routes,
NameServerGroups: nsGroups, NameServerGroups: nsGroups,
@ -1793,21 +1788,28 @@ func addAllGroup(account *Account) error {
} }
account.Groups = map[string]*Group{allGroup.ID: allGroup} account.Groups = map[string]*Group{allGroup.ID: allGroup}
defaultRule := &Rule{ id := xid.New().String()
ID: xid.New().String(),
defaultPolicy := &Policy{
ID: id,
Name: DefaultRuleName, Name: DefaultRuleName,
Description: DefaultRuleDescription, Description: DefaultRuleDescription,
Disabled: false, Enabled: true,
Source: []string{allGroup.ID}, Rules: []*PolicyRule{
Destination: []string{allGroup.ID}, {
ID: id,
Name: DefaultRuleName,
Description: DefaultRuleDescription,
Enabled: true,
Sources: []string{allGroup.ID},
Destinations: []string{allGroup.ID},
Bidirectional: true,
Protocol: PolicyRuleProtocolALL,
Action: PolicyTrafficActionAccept,
},
},
} }
account.Rules = map[string]*Rule{defaultRule.ID: defaultRule}
// TODO: after migration we need to drop rule and create policy directly
defaultPolicy, err := RuleToPolicy(defaultRule)
if err != nil {
return fmt.Errorf("convert rule to policy: %w", err)
}
account.Policies = []*Policy{defaultPolicy} account.Policies = []*Policy{defaultPolicy}
} }
return nil return nil

View File

@ -96,16 +96,6 @@ func verifyNewAccountHasDefaultFields(t *testing.T, account *Account, createdBy
if account.Domain != domain { if account.Domain != domain {
t.Errorf("expecting newly created account to have domain %s, got %s", domain, account.Domain) t.Errorf("expecting newly created account to have domain %s, got %s", domain, account.Domain)
} }
if len(account.Rules) != 1 {
t.Errorf("expecting newly created account to have 1 rule, got %d", len(account.Rules))
}
for _, rule := range account.Rules {
if rule.Name != "Default" {
t.Errorf("expecting newly created account to have Default rule, got %s", rule.Name)
}
}
} }
func TestAccount_GetPeerNetworkMap(t *testing.T) { func TestAccount_GetPeerNetworkMap(t *testing.T) {
@ -1528,13 +1518,6 @@ func TestAccount_Copy(t *testing.T) {
Peers: []string{"peer1"}, Peers: []string{"peer1"},
}, },
}, },
Rules: map[string]*Rule{
"rule1": {
ID: "rule1",
Destination: []string{},
Source: []string{},
},
},
Policies: []*Policy{ Policies: []*Policy{
{ {
ID: "policy1", ID: "policy1",

View File

@ -159,18 +159,6 @@ func restore(file string) (*FileStore, error) {
if account.Policies == nil { if account.Policies == nil {
account.Policies = make([]*Policy, 0) account.Policies = make([]*Policy, 0)
} }
for _, rule := range account.Rules {
policy, err := RuleToPolicy(rule)
if err != nil {
log.Errorf("unable to migrate rule to policy: %v", err)
continue
}
// don't update policies from rules, rules deprecated,
// only append not existed rules as part of the migration process
if _, ok := policies[policy.ID]; !ok {
account.Policies = append(account.Policies, policy)
}
}
// for data migration. Can be removed once most base will be with labels // for data migration. Can be removed once most base will be with labels
existingLabels := account.getPeerDNSLabels() existingLabels := account.getPeerDNSLabels()
@ -342,13 +330,6 @@ func (s *FileStore) SaveAccount(account *Account) error {
s.PrivateDomain2AccountID[accountCopy.Domain] = accountCopy.Id s.PrivateDomain2AccountID[accountCopy.Domain] = accountCopy.Id
} }
accountCopy.Rules = make(map[string]*Rule)
for _, policy := range accountCopy.Policies {
for _, rule := range policy.Rules {
accountCopy.Rules[rule.ID] = rule.ToRule()
}
}
return s.persist(s.storeFile) return s.persist(s.storeFile)
} }

View File

@ -193,18 +193,18 @@ func TestStore(t *testing.T) {
Name: "all", Name: "all",
Peers: []string{"testpeer"}, Peers: []string{"testpeer"},
} }
account.Rules["all"] = &Rule{
ID: "all",
Name: "all",
Source: []string{"all"},
Destination: []string{"all"},
Flow: TrafficFlowBidirect,
}
account.Policies = append(account.Policies, &Policy{ account.Policies = append(account.Policies, &Policy{
ID: "all", ID: "all",
Name: "all", Name: "all",
Enabled: true, Enabled: true,
Rules: []*PolicyRule{account.Rules["all"].ToPolicyRule()}, Rules: []*PolicyRule{
{
ID: "all",
Name: "all",
Sources: []string{"all"},
Destinations: []string{"all"},
},
},
}) })
account.Policies = append(account.Policies, &Policy{ account.Policies = append(account.Policies, &Policy{
ID: "dmz", ID: "dmz",
@ -317,41 +317,6 @@ func TestRestore(t *testing.T) {
require.Len(t, store.TokenID2UserID, 1, "failed to restore a FileStore wrong TokenID2UserID mapping length") require.Len(t, store.TokenID2UserID, 1, "failed to restore a FileStore wrong TokenID2UserID mapping length")
} }
// TODO: outdated, delete this
func TestRestorePolicies_Migration(t *testing.T) {
storeDir := t.TempDir()
err := util.CopyFileContents("testdata/store_policy_migrate.json", filepath.Join(storeDir, "store.json"))
if err != nil {
t.Fatal(err)
}
store, err := NewFileStore(storeDir, nil)
if err != nil {
return
}
account := store.Accounts["bf1c8084-ba50-4ce7-9439-34653001fc3b"]
require.Len(t, account.Groups, 1, "failed to restore a FileStore file - missing Account Groups")
require.Len(t, account.Rules, 1, "failed to restore a FileStore file - missing Account Rules")
require.Len(t, account.Policies, 1, "failed to restore a FileStore file - missing Account Policies")
policy := account.Policies[0]
require.Equal(t, policy.Name, "Default", "failed to restore a FileStore file - missing Account Policies Name")
require.Equal(t, policy.Description,
"This is a default rule that allows connections between all the resources",
"failed to restore a FileStore file - missing Account Policies Description")
require.NoError(t, err, "failed to upldate query")
require.Len(t, policy.Rules, 1, "failed to restore a FileStore file - missing Account Policy Rules")
require.Equal(t, policy.Rules[0].Action, PolicyTrafficActionAccept, "failed to restore a FileStore file - missing Account Policies Action")
require.Equal(t, policy.Rules[0].Destinations,
[]string{"cfefqs706sqkneg59g3g"},
"failed to restore a FileStore file - missing Account Policies Destinations")
require.Equal(t, policy.Rules[0].Sources,
[]string{"cfefqs706sqkneg59g3g"},
"failed to restore a FileStore file - missing Account Policies Sources")
}
func TestRestoreGroups_Migration(t *testing.T) { func TestRestoreGroups_Migration(t *testing.T) {
storeDir := t.TempDir() storeDir := t.TempDir()

View File

@ -83,41 +83,57 @@ func TestAccount_getPeersByPolicy(t *testing.T) {
}, },
}, },
}, },
Rules: map[string]*Rule{ Policies: []*Policy{
"RuleDefault": { {
ID: "RuleDefault", ID: "RuleDefault",
Name: "Default", Name: "Default",
Description: "This is a default rule that allows connections between all the resources", Description: "This is a default rule that allows connections between all the resources",
Source: []string{ Enabled: true,
Rules: []*PolicyRule{
{
ID: "RuleDefault",
Name: "Default",
Description: "This is a default rule that allows connections between all the resources",
Bidirectional: true,
Enabled: true,
Protocol: PolicyRuleProtocolALL,
Action: PolicyTrafficActionAccept,
Sources: []string{
"GroupAll", "GroupAll",
}, },
Destination: []string{ Destinations: []string{
"GroupAll", "GroupAll",
}, },
}, },
"RuleSwarm": { },
},
{
ID: "RuleSwarm", ID: "RuleSwarm",
Name: "Swarm", Name: "Swarm",
Description: "", Description: "No description",
Source: []string{ Enabled: true,
Rules: []*PolicyRule{
{
ID: "RuleSwarm",
Name: "Swarm",
Description: "No description",
Bidirectional: true,
Enabled: true,
Protocol: PolicyRuleProtocolALL,
Action: PolicyTrafficActionAccept,
Sources: []string{
"GroupSwarm", "GroupSwarm",
"GroupAll", "GroupAll",
}, },
Destination: []string{ Destinations: []string{
"GroupSwarm", "GroupSwarm",
}, },
}, },
}, },
},
},
} }
rule1, err := RuleToPolicy(account.Rules["RuleDefault"])
assert.NoError(t, err)
rule2, err := RuleToPolicy(account.Rules["RuleSwarm"])
assert.NoError(t, err)
account.Policies = append(account.Policies, rule1, rule2)
t.Run("check that all peers get map", func(t *testing.T) { t.Run("check that all peers get map", func(t *testing.T) {
for _, p := range account.Peers { for _, p := range account.Peers {
peers, firewallRules := account.getPeerConnectionResources(p.ID) peers, firewallRules := account.getPeerConnectionResources(p.ID)
@ -307,41 +323,56 @@ func TestAccount_getPeersByPolicyDirect(t *testing.T) {
}, },
}, },
}, },
Rules: map[string]*Rule{ Policies: []*Policy{
"RuleDefault": { {
ID: "RuleDefault", ID: "RuleDefault",
Name: "Default", Name: "Default",
Disabled: true,
Description: "This is a default rule that allows connections between all the resources", Description: "This is a default rule that allows connections between all the resources",
Source: []string{ Enabled: false,
Rules: []*PolicyRule{
{
ID: "RuleDefault",
Name: "Default",
Description: "This is a default rule that allows connections between all the resources",
Bidirectional: true,
Enabled: false,
Protocol: PolicyRuleProtocolALL,
Action: PolicyTrafficActionAccept,
Sources: []string{
"GroupAll", "GroupAll",
}, },
Destination: []string{ Destinations: []string{
"GroupAll", "GroupAll",
}, },
}, },
"RuleSwarm": { },
},
{
ID: "RuleSwarm", ID: "RuleSwarm",
Name: "Swarm", Name: "Swarm",
Description: "", Description: "No description",
Source: []string{ Enabled: true,
Rules: []*PolicyRule{
{
ID: "RuleSwarm",
Name: "Swarm",
Description: "No description",
Bidirectional: true,
Enabled: true,
Protocol: PolicyRuleProtocolALL,
Action: PolicyTrafficActionAccept,
Sources: []string{
"GroupSwarm", "GroupSwarm",
}, },
Destination: []string{ Destinations: []string{
"peerF", "peerF",
}, },
}, },
}, },
},
},
} }
rule1, err := RuleToPolicy(account.Rules["RuleDefault"])
assert.NoError(t, err)
rule2, err := RuleToPolicy(account.Rules["RuleSwarm"])
assert.NoError(t, err)
account.Policies = append(account.Policies, rule1, rule2)
t.Run("check first peer map", func(t *testing.T) { t.Run("check first peer map", func(t *testing.T) {
peers, firewallRules := account.getPeerConnectionResources("peerB") peers, firewallRules := account.getPeerConnectionResources("peerB")
assert.Contains(t, peers, account.Peers["peerC"]) assert.Contains(t, peers, account.Peers["peerC"])

View File

@ -156,11 +156,6 @@ func (s *SqliteStore) SaveAccount(account *Account) error {
account.GroupsG = append(account.GroupsG, *group) account.GroupsG = append(account.GroupsG, *group)
} }
for id, rule := range account.Rules {
rule.ID = id
account.RulesG = append(account.RulesG, *rule)
}
for id, route := range account.Routes { for id, route := range account.Routes {
route.ID = id route.ID = id
account.RoutesG = append(account.RoutesG, *route) account.RoutesG = append(account.RoutesG, *route)
@ -356,7 +351,6 @@ func (s *SqliteStore) GetAllAccounts() (all []*Account) {
func (s *SqliteStore) GetAccount(accountID string) (*Account, error) { func (s *SqliteStore) GetAccount(accountID string) (*Account, error) {
var account Account var account Account
result := s.db.Model(&account). result := s.db.Model(&account).
Preload("UsersG.PATsG"). // have to be specifies as this is nester reference Preload("UsersG.PATsG"). // have to be specifies as this is nester reference
Preload(clause.Associations). Preload(clause.Associations).
@ -403,12 +397,6 @@ func (s *SqliteStore) GetAccount(accountID string) (*Account, error) {
} }
account.GroupsG = nil account.GroupsG = nil
account.Rules = make(map[string]*Rule, len(account.RulesG))
for _, rule := range account.RulesG {
account.Rules[rule.ID] = rule.Copy()
}
account.RulesG = nil
account.Routes = make(map[string]*route.Route, len(account.RoutesG)) account.Routes = make(map[string]*route.Route, len(account.RoutesG))
for _, route := range account.RoutesG { for _, route := range account.RoutesG {
account.Routes[route.ID] = route.Copy() account.Routes[route.ID] = route.Copy()