| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package compute
- import (
- "reflect"
- "strings"
- "yunion.io/x/jsonutils"
- "yunion.io/x/pkg/gotypes"
- "yunion.io/x/pkg/utils"
- "yunion.io/x/onecloud/pkg/apis"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/util/tagutils"
- )
- const (
- PROJECT_MAPPING_STATUS_AVAILABLE = "available"
- MAPPING_CONDITION_AND = "and"
- MAPPING_CONDITION_OR = "or"
- )
- type ProjectMappingRuleInfo struct {
- // 标签列表, 不可为空
- Tags tagutils.TTagSet `json:"tags"`
- // 条件表达式
- // enmu: and, or
- // default: and
- Condition string `json:"condition"`
- // 是否自动根据标签值创建项目, 仅标签列表中有且仅有一个没有value的key时支持
- AutoCreateProject bool `json:"auto_create_project"`
- // 符合条件时,资源放置的项目id, 此参数和auto_create_project互斥
- ProjectId string `json:"project_id"`
- // 只读信息
- // swagger:ignore
- Project string `json:"project"`
- // swagger:ignore
- DomainId string `json:"domain_id"`
- // 只读信息
- // swagger:ignore
- Domain string `json:"domain"`
- }
- func (rule ProjectMappingRuleInfo) IsWide() bool {
- for _, tag := range rule.Tags {
- if len(tag.Value) == 0 {
- return true
- }
- }
- return false
- }
- type MappingRules []ProjectMappingRuleInfo
- func (rules MappingRules) Rules() MappingRules {
- normal := []ProjectMappingRuleInfo{}
- wide := []ProjectMappingRuleInfo{}
- for _, rule := range rules {
- if rule.IsWide() {
- wide = append(wide, rule)
- } else {
- normal = append(normal, rule)
- }
- }
- return append(normal, wide...)
- }
- func (rule *ProjectMappingRuleInfo) Validate() error {
- if len(rule.Tags) == 0 {
- return httperrors.NewInputParameterError("missing tags")
- }
- if len(rule.Condition) == 0 {
- rule.Condition = MAPPING_CONDITION_AND
- }
- if !utils.IsInStringArray(rule.Condition, []string{MAPPING_CONDITION_AND, MAPPING_CONDITION_OR}) {
- return httperrors.NewInputParameterError("invalid condition")
- }
- emptyValueTags := 0
- for _, tag := range rule.Tags {
- if len(tag.Key) == 0 {
- return httperrors.NewInputParameterError("missing tag key for")
- }
- if len(tag.Value) == 0 {
- emptyValueTags++
- }
- }
- if emptyValueTags != 1 && rule.AutoCreateProject {
- return httperrors.NewInputParameterError("not support auto_create_project")
- }
- if !rule.AutoCreateProject && len(rule.ProjectId) == 0 && len(rule.Project) == 0 {
- return httperrors.NewInputParameterError("missing project_id")
- }
- return nil
- }
- // return domainId, projectId, newProj, isMatch
- func (self *ProjectMappingRuleInfo) IsMatchTags(_extTags map[string]string) (string, string, string, bool) {
- newProj := ""
- extTags := map[string]string{}
- for k, v := range _extTags {
- extTags[strings.ToUpper(k)] = v
- }
- switch self.Condition {
- case MAPPING_CONDITION_AND:
- for _, tag := range self.Tags {
- extTag, ok := extTags[strings.ToUpper(tag.Key)]
- if !ok || (len(tag.Value) > 0 && tag.Value != extTag) {
- return "", "", "", false
- }
- if self.AutoCreateProject && len(tag.Value) == 0 && len(extTag) > 0 {
- newProj = extTag
- }
- }
- if !self.AutoCreateProject && len(self.ProjectId) == 0 && len(self.Project) > 0 {
- newProj = self.Project
- }
- return self.DomainId, self.ProjectId, newProj, true
- case MAPPING_CONDITION_OR:
- for _, tag := range self.Tags {
- extTag, ok := extTags[strings.ToUpper(tag.Key)]
- if ok && (len(tag.Value) == 0 || tag.Value == extTag) {
- if self.AutoCreateProject && len(tag.Value) == 0 && len(extTag) > 0 {
- return "", "", extTag, true
- } else if !self.AutoCreateProject && len(self.ProjectId) == 0 && len(self.Project) > 0 {
- return self.DomainId, self.ProjectId, self.Project, true
- } else {
- return self.DomainId, self.ProjectId, "", true
- }
- }
- }
- }
- return "", "", "", false
- }
- func (rules MappingRules) Validate() error {
- for i := range rules {
- err := rules[i].Validate()
- if err != nil {
- return err
- }
- }
- return nil
- }
- type ProjectMappingRuleInfoDetails struct {
- ProjectMappingRuleInfo
- Project string `json:"project"`
- TenantId string `json:"tenant_id"`
- Tenant string `json:"tenant"`
- Domain string `json:"domain"`
- }
- type SProjectMappingAccount struct {
- Id string `json:"id"`
- Name string `json:"name"`
- }
- type ProjectMappingDetails struct {
- SProjectMapping
- apis.EnabledStatusInfrasResourceBaseDetails
- Rules []ProjectMappingRuleInfoDetails `json:"rules"`
- // 所绑定的云账号列表
- Accounts []SProjectMappingAccount `json:"accounts"`
- // 所绑定的云订阅列表
- Managers []SProjectMappingAccount `json:"managers"`
- }
- type ProjectMappingCreateInput struct {
- apis.EnabledStatusInfrasResourceBaseCreateInput
- // 根据标签key匹配的规则会默认排到列表最后
- Rules MappingRules
- }
- type ProjectMappingListInput struct {
- apis.EnabledStatusInfrasResourceBaseListInput
- }
- type ProjectMappingResourceInfo struct {
- ProjectMapping string `json:"project_mapping"`
- }
- type ProjectMappingUpdateInput struct {
- apis.EnabledStatusInfrasResourceBaseUpdateInput
- // 根据标签key匹配的规则会默认排到列表最后
- Rules MappingRules
- }
- type ProjectMappingFilterListInput struct {
- ProjectMappingId string `json:"project_mapping_id"`
- OrderByProjectMapping string `json:"order_by_project_mapping"`
- }
- func (self MappingRules) String() string {
- return jsonutils.Marshal(self).String()
- }
- func (self MappingRules) IsZero() bool {
- if len(self) == 0 {
- return true
- }
- return false
- }
- func init() {
- gotypes.RegisterSerializable(reflect.TypeOf(&MappingRules{}), func() gotypes.ISerializable {
- return &MappingRules{}
- })
- }
|