yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/openstack/loadbalanceracl.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 openstack 16 17 import ( 18 "fmt" 19 "time" 20 21 "github.com/pkg/errors" 22 23 "yunion.io/x/jsonutils" 24 25 "yunion.io/x/cloudmux/pkg/cloudprovider" 26 "yunion.io/x/cloudmux/pkg/multicloud" 27 ) 28 29 type AclEntrys struct { 30 AclEntry []AclEntry 31 } 32 33 type AclEntry struct { 34 AclEntryComment string 35 AclEntryIP string 36 } 37 38 type SLoadbalancerAcl struct { 39 multicloud.SResourceBase 40 OpenStackTags 41 listener *SLoadbalancerListener 42 } 43 44 func (acl *SLoadbalancerAcl) GetAclListenerID() string { 45 return acl.listener.ID 46 } 47 48 func (acl *SLoadbalancerAcl) GetName() string { 49 return acl.listener.Name + "AllowedCidrs" 50 } 51 52 func (acl *SLoadbalancerAcl) GetId() string { 53 return acl.listener.ID 54 } 55 56 func (acl *SLoadbalancerAcl) GetGlobalId() string { 57 return acl.listener.ID 58 } 59 60 func (acl *SLoadbalancerAcl) GetStatus() string { 61 return "" 62 } 63 64 func (acl *SLoadbalancerAcl) IsEmulated() bool { 65 return false 66 } 67 68 func (acl *SLoadbalancerAcl) Refresh() error { 69 return acl.listener.Refresh() 70 } 71 72 func (acl *SLoadbalancerAcl) GetAclEntries() []cloudprovider.SLoadbalancerAccessControlListEntry { 73 aclEntrys := []cloudprovider.SLoadbalancerAccessControlListEntry{} 74 for i := 0; i < len(acl.listener.AllowedCidrs); i++ { 75 aclEntry := cloudprovider.SLoadbalancerAccessControlListEntry{} 76 aclEntry.CIDR = acl.listener.AllowedCidrs[i] 77 aclEntry.Comment = "AllowedCidr" 78 aclEntrys = append(aclEntrys, aclEntry) 79 } 80 return aclEntrys 81 } 82 83 func (region *SRegion) UpdateLoadbalancerListenerAllowedCidrs(listenerId string, cidrs []string) error { 84 params := jsonutils.NewDict() 85 listenerParam := jsonutils.NewDict() 86 listenerParam.Add(jsonutils.NewStringArray(cidrs), "allowed_cidrs") 87 params.Add(listenerParam, "listener") 88 _, err := region.lbUpdate(fmt.Sprintf("/v2/lbaas/listeners/%s", listenerId), params) 89 if err != nil { 90 return errors.Wrapf(err, `region.lbUpdate(/v2/lbaas/listeners/%s, params)`, listenerId) 91 } 92 return nil 93 } 94 95 func (acl *SLoadbalancerAcl) Delete() error { 96 // ensure listener status 97 err := waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute) 98 if err != nil { 99 return errors.Wrap(err, `waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute)`) 100 } 101 err = acl.listener.region.UpdateLoadbalancerListenerAllowedCidrs(acl.listener.ID, []string{}) 102 if err != nil { 103 return errors.Wrap(err, `acl.listener.region.UpdateLoadbalancerListenerAllowedCidrs(acl.listener.ID, []string{})`) 104 } 105 err = waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute) 106 if err != nil { 107 return errors.Wrap(err, `waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute)`) 108 } 109 return nil 110 } 111 112 func (region *SRegion) GetLoadbalancerAclDetail(aclId string) (*SLoadbalancerAcl, error) { 113 listener, err := region.GetLoadbalancerListenerbyId(aclId) 114 if err != nil { 115 return nil, errors.Wrapf(err, "region.GetLoadbalancerListenerbyId(%s)", aclId) 116 } 117 acl := SLoadbalancerAcl{} 118 acl.listener = listener 119 return &acl, nil 120 } 121 122 func (region *SRegion) GetLoadBalancerAcls() ([]SLoadbalancerAcl, error) { 123 listeners, err := region.GetLoadbalancerListeners() 124 if err != nil { 125 return nil, errors.Wrap(err, "region.GetLoadbalancerListeners()") 126 } 127 acls := []SLoadbalancerAcl{} 128 for i := 0; i < len(listeners); i++ { 129 if len(listeners[i].AllowedCidrs) < 1 { 130 continue 131 } 132 acl := new(SLoadbalancerAcl) 133 acl.listener = &listeners[i] 134 acls = append(acls, *acl) 135 136 } 137 return acls, nil 138 } 139 140 func (region *SRegion) CreateLoadBalancerAcl(acl *cloudprovider.SLoadbalancerAccessControlList) (*SLoadbalancerAcl, error) { 141 if !acl.AccessControlEnable { 142 return nil, errors.Wrap(fmt.Errorf("only support allowed cidrs"), "CreateLoadBalancerAcl") 143 } 144 if len(acl.ListenerId) < 1 { 145 return nil, errors.Wrap(fmt.Errorf("loadbalanceracl must band to a loadbalancerlistener"), "CreateLoadBalancerAcl") 146 } 147 cidrs := []string{} 148 for i := 0; i < len(acl.Entrys); i++ { 149 cidrs = append(cidrs, acl.Entrys[i].CIDR) 150 } 151 sacl, err := region.GetLoadbalancerAclDetail(acl.ListenerId) 152 if err != nil { 153 return nil, errors.Wrapf(err, "region.GetLoadbalancerAclDetail(%s)", acl.ListenerId) 154 } 155 // ensure listener status 156 err = waitLbResStatus(sacl.listener, 10*time.Second, 8*time.Minute) 157 if err != nil { 158 return nil, errors.Wrap(err, `waitLbResStatus(sacl.listener, 10*time.Second, 8*time.Minute)`) 159 } 160 return sacl, region.UpdateLoadbalancerListenerAllowedCidrs(acl.ListenerId, cidrs) 161 } 162 163 func (acl *SLoadbalancerAcl) Sync(_acl *cloudprovider.SLoadbalancerAccessControlList) error { 164 // ensure listener status 165 err := waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute) 166 if err != nil { 167 return errors.Wrap(err, "waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute)") 168 } 169 170 cidrs := []string{} 171 for i := 0; i < len(_acl.Entrys); i++ { 172 cidrs = append(cidrs, _acl.Entrys[i].CIDR) 173 } 174 err = acl.listener.region.UpdateLoadbalancerListenerAllowedCidrs(acl.listener.ID, cidrs) 175 if err != nil { 176 return errors.Wrapf(err, "UpdateLoadbalancerListenerAllowedCidrs(%s, cidrs)", acl.listener.ID) 177 } 178 err = waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute) 179 if err != nil { 180 return errors.Wrap(err, "waitLbResStatus(acl.listener, 10*time.Second, 8*time.Minute)") 181 } 182 return nil 183 } 184 185 func (acl *SLoadbalancerAcl) GetProjectId() string { 186 return acl.listener.ProjectID 187 }