yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/cloudprovider/access_group.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package cloudprovider
    16  
    17  import (
    18  	"fmt"
    19  	"sort"
    20  	"strings"
    21  
    22  	"yunion.io/x/log"
    23  	"yunion.io/x/pkg/errors"
    24  	"yunion.io/x/pkg/utils"
    25  )
    26  
    27  type SAccessGroup struct {
    28  	Name           string
    29  	NetworkType    string
    30  	FileSystemType string
    31  	Desc           string
    32  }
    33  
    34  type TRWAccessType string
    35  type TUserAccessType string
    36  
    37  const (
    38  	RWAccessTypeRW = TRWAccessType("RW")
    39  	RWAccessTypeR  = TRWAccessType("R")
    40  
    41  	UserAccessTypeNoRootSquash = TUserAccessType("no_root_squash")
    42  	UserAccessTypeRootSquash   = TUserAccessType("root_squash")
    43  	UserAccessTypeAllSquash    = TUserAccessType("all_squash")
    44  )
    45  
    46  func GetAccessGroupRuleInfo(group ICloudAccessGroup) (AccessGroupRuleInfo, error) {
    47  	ret := AccessGroupRuleInfo{
    48  		MinPriority:             group.GetMinPriority(),
    49  		MaxPriority:             group.GetMaxPriority(),
    50  		SupportedUserAccessType: group.GetSupporedUserAccessTypes(),
    51  	}
    52  	var err error
    53  	ret.Rules, err = group.GetRules()
    54  	if err != nil {
    55  		return ret, errors.Wrapf(err, "GetRules")
    56  	}
    57  	return ret, nil
    58  }
    59  
    60  type AccessGroupRule struct {
    61  	Id             string
    62  	ExternalId     string
    63  	Priority       int
    64  	RWAccessType   TRWAccessType
    65  	UserAccessType TUserAccessType
    66  	Source         string
    67  }
    68  
    69  func (self AccessGroupRule) String() string {
    70  	return fmt.Sprintf("%s-%s-%s", self.RWAccessType, self.UserAccessType, self.Source)
    71  }
    72  
    73  type AccessGroupRuleSet []AccessGroupRule
    74  
    75  func (srs AccessGroupRuleSet) Len() int {
    76  	return len(srs)
    77  }
    78  
    79  func (srs AccessGroupRuleSet) Swap(i, j int) {
    80  	srs[i], srs[j] = srs[j], srs[i]
    81  }
    82  
    83  func (srs AccessGroupRuleSet) Less(i, j int) bool {
    84  	return srs[i].Priority < srs[j].Priority || (srs[i].Priority == srs[j].Priority && srs[i].String() < srs[j].String())
    85  }
    86  
    87  type AccessGroupRuleInfo struct {
    88  	MaxPriority             int
    89  	MinPriority             int
    90  	SupportedUserAccessType []TUserAccessType
    91  	Rules                   AccessGroupRuleSet
    92  }
    93  
    94  func (self *AccessGroupRuleInfo) Sort() {
    95  	if self.MinPriority < self.MaxPriority {
    96  		sort.Sort(self.Rules)
    97  		return
    98  	}
    99  	sort.Sort(sort.Reverse(self.Rules))
   100  }
   101  
   102  func CompareAccessGroupRules(src, dest AccessGroupRuleInfo, debug bool) (common, added, removed AccessGroupRuleSet) {
   103  	src.Sort()
   104  	dest.Sort()
   105  	var addPriority = func(init int, min, max int) int {
   106  		inc := 1
   107  		if max < min {
   108  			max, min, inc = min, max, -1
   109  		}
   110  		if init >= max || init <= min {
   111  			return init
   112  		}
   113  		return init + inc
   114  	}
   115  	i, j, priority := 0, 0, (dest.MinPriority-1+dest.MaxPriority)/2
   116  	for i < len(src.Rules) || j < len(dest.Rules) {
   117  		if i < len(src.Rules) && j < len(dest.Rules) {
   118  			destRuleStr := dest.Rules[j].String()
   119  			srcRuleStr := src.Rules[i].String()
   120  			if debug {
   121  				log.Debugf("compare src %s priority(%d) %s -> dest %s priority(%d) %s\n",
   122  					src.Rules[i].ExternalId, src.Rules[i].Priority, src.Rules[i].String(),
   123  					dest.Rules[j].ExternalId, dest.Rules[j].Priority, dest.Rules[j].String())
   124  			}
   125  			cmp := strings.Compare(destRuleStr, srcRuleStr)
   126  			if cmp == 0 {
   127  				dest.Rules[j].Id = src.Rules[i].Id
   128  				common = append(common, dest.Rules[j])
   129  				priority = dest.Rules[j].Priority
   130  				i++
   131  				j++
   132  			} else if cmp < 0 {
   133  				removed = append(removed, dest.Rules[j])
   134  				j++
   135  			} else {
   136  				if isIn, _ := utils.InArray(src.Rules[i].UserAccessType, dest.SupportedUserAccessType); isIn {
   137  					priority = addPriority(priority, dest.MinPriority, dest.MaxPriority)
   138  					src.Rules[i].Priority = priority
   139  					added = append(added, src.Rules[i])
   140  				}
   141  				i++
   142  			}
   143  		} else if i >= len(src.Rules) {
   144  			removed = append(removed, dest.Rules[j])
   145  			j++
   146  		} else if j >= len(dest.Rules) {
   147  			if isIn, _ := utils.InArray(src.Rules[i].UserAccessType, dest.SupportedUserAccessType); isIn {
   148  				priority = addPriority(priority, dest.MinPriority, dest.MaxPriority)
   149  				src.Rules[i].Priority = priority
   150  				added = append(added, src.Rules[i])
   151  			}
   152  			i++
   153  		}
   154  	}
   155  	return common, added, removed
   156  }