github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/actor/cfnetworkingaction/policy.go (about) 1 package cfnetworkingaction 2 3 import ( 4 "code.cloudfoundry.org/cfnetworking-cli-api/cfnetworking/cfnetv1" 5 "code.cloudfoundry.org/cli/actor/actionerror" 6 "code.cloudfoundry.org/cli/actor/v3action" 7 ) 8 9 type Policy struct { 10 SourceName string 11 DestinationName string 12 Protocol string 13 DestinationSpaceName string 14 DestinationOrgName string 15 StartPort int 16 EndPort int 17 } 18 19 func (actor Actor) AddNetworkPolicy(srcSpaceGUID, srcAppName, destSpaceGUID, destAppName, protocol string, startPort, endPort int) (Warnings, error) { 20 var allWarnings Warnings 21 22 srcApp, warnings, err := actor.V3Actor.GetApplicationByNameAndSpace(srcAppName, srcSpaceGUID) 23 allWarnings = append(allWarnings, warnings...) 24 if err != nil { 25 return allWarnings, err 26 } 27 28 destApp, warnings, err := actor.V3Actor.GetApplicationByNameAndSpace(destAppName, destSpaceGUID) 29 allWarnings = append(allWarnings, warnings...) 30 if err != nil { 31 return allWarnings, err 32 } 33 34 err = actor.NetworkingClient.CreatePolicies([]cfnetv1.Policy{ 35 { 36 Source: cfnetv1.PolicySource{ 37 ID: srcApp.GUID, 38 }, 39 Destination: cfnetv1.PolicyDestination{ 40 ID: destApp.GUID, 41 Protocol: cfnetv1.PolicyProtocol(protocol), 42 Ports: cfnetv1.Ports{ 43 Start: startPort, 44 End: endPort, 45 }, 46 }, 47 }, 48 }) 49 return allWarnings, err 50 } 51 52 func (actor Actor) NetworkPoliciesBySpace(spaceGUID string) ([]Policy, Warnings, error) { 53 var allWarnings Warnings 54 55 applications, warnings, err := actor.V3Actor.GetApplicationsBySpace(spaceGUID) 56 allWarnings = append(allWarnings, warnings...) 57 if err != nil { 58 return []Policy{}, allWarnings, err 59 } 60 61 policies, warnings, err := actor.getPoliciesForApplications(applications) 62 allWarnings = append(allWarnings, warnings...) 63 if err != nil { 64 return []Policy{}, allWarnings, err 65 } 66 67 return policies, allWarnings, nil 68 } 69 70 func (actor Actor) NetworkPoliciesBySpaceAndAppName(spaceGUID string, srcAppName string) ([]Policy, Warnings, error) { 71 var allWarnings Warnings 72 73 srcApp, warnings, err := actor.V3Actor.GetApplicationByNameAndSpace(srcAppName, spaceGUID) 74 allWarnings = append(allWarnings, warnings...) 75 if err != nil { 76 return []Policy{}, allWarnings, err 77 } 78 79 policies, warnings, err := actor.getPoliciesForApplications([]v3action.Application{srcApp}) 80 allWarnings = append(allWarnings, warnings...) 81 if err != nil { 82 return []Policy{}, allWarnings, err 83 } 84 85 return policies, allWarnings, nil 86 } 87 88 func (actor Actor) RemoveNetworkPolicy(srcSpaceGUID, srcAppName, destSpaceGUID, destAppName, protocol string, startPort, endPort int) (Warnings, error) { 89 var allWarnings Warnings 90 91 srcApp, warnings, err := actor.V3Actor.GetApplicationByNameAndSpace(srcAppName, srcSpaceGUID) 92 allWarnings = append(allWarnings, warnings...) 93 if err != nil { 94 return allWarnings, err 95 } 96 97 destApp, warnings, err := actor.V3Actor.GetApplicationByNameAndSpace(destAppName, destSpaceGUID) 98 allWarnings = append(allWarnings, warnings...) 99 if err != nil { 100 return allWarnings, err 101 } 102 103 policyToRemove := cfnetv1.Policy{ 104 Source: cfnetv1.PolicySource{ 105 ID: srcApp.GUID, 106 }, 107 Destination: cfnetv1.PolicyDestination{ 108 ID: destApp.GUID, 109 Protocol: cfnetv1.PolicyProtocol(protocol), 110 Ports: cfnetv1.Ports{ 111 Start: startPort, 112 End: endPort, 113 }, 114 }, 115 } 116 117 v1Policies, err := actor.NetworkingClient.ListPolicies(srcApp.GUID) 118 if err != nil { 119 return allWarnings, err 120 } 121 122 for _, v1Policy := range v1Policies { 123 if v1Policy == policyToRemove { 124 return allWarnings, actor.NetworkingClient.RemovePolicies([]cfnetv1.Policy{policyToRemove}) 125 } 126 } 127 128 return allWarnings, actionerror.PolicyDoesNotExistError{} 129 } 130 131 func filterPoliciesWithoutMatchingSourceGUIDs(v1Policies []cfnetv1.Policy, srcAppGUIDs []string) []cfnetv1.Policy { 132 srcGUIDsSet := map[string]struct{}{} 133 for _, srcGUID := range srcAppGUIDs { 134 srcGUIDsSet[srcGUID] = struct{}{} 135 } 136 137 var toReturn []cfnetv1.Policy 138 for _, policy := range v1Policies { 139 if _, ok := srcGUIDsSet[policy.Source.ID]; ok { 140 toReturn = append(toReturn, policy) 141 } 142 } 143 144 return toReturn 145 } 146 147 func uniqueSpaceGUIDs(applications []v3action.Application) []string { 148 var spaceGUIDs []string 149 occurances := map[string]struct{}{} 150 for _, app := range applications { 151 if _, ok := occurances[app.SpaceGUID]; !ok { 152 spaceGUIDs = append(spaceGUIDs, app.SpaceGUID) 153 occurances[app.SpaceGUID] = struct{}{} 154 } 155 } 156 return spaceGUIDs 157 } 158 159 func uniqueOrgGUIDs(spaces []v3action.Space) []string { 160 var orgGUIDs []string 161 occurances := map[string]struct{}{} 162 for _, space := range spaces { 163 if _, ok := occurances[space.OrganizationGUID]; !ok { 164 orgGUIDs = append(orgGUIDs, space.OrganizationGUID) 165 occurances[space.OrganizationGUID] = struct{}{} 166 } 167 } 168 return orgGUIDs 169 } 170 171 func uniqueDestGUIDs(policies []cfnetv1.Policy) []string { 172 var destAppGUIDs []string 173 occurances := map[string]struct{}{} 174 for _, policy := range policies { 175 if _, ok := occurances[policy.Destination.ID]; !ok { 176 destAppGUIDs = append(destAppGUIDs, policy.Destination.ID) 177 occurances[policy.Destination.ID] = struct{}{} 178 } 179 } 180 return destAppGUIDs 181 } 182 183 func (actor Actor) orgNamesBySpaceGUID(spaces []v3action.Space) (map[string]string, v3action.Warnings, error) { 184 orgGUIDs := uniqueOrgGUIDs(spaces) 185 186 orgs, warnings, err := actor.V3Actor.GetOrganizationsByGUIDs(orgGUIDs...) 187 if err != nil { 188 return nil, warnings, err 189 } 190 191 orgNamesByGUID := make(map[string]string, len(orgs)) 192 for _, org := range orgs { 193 orgNamesByGUID[org.GUID] = org.Name 194 } 195 196 orgNamesBySpaceGUID := make(map[string]string, len(spaces)) 197 for _, space := range spaces { 198 orgNamesBySpaceGUID[space.GUID] = orgNamesByGUID[space.OrganizationGUID] 199 } 200 201 return orgNamesBySpaceGUID, warnings, nil 202 } 203 204 func (actor Actor) getPoliciesForApplications(applications []v3action.Application) ([]Policy, v3action.Warnings, error) { 205 var allWarnings v3action.Warnings 206 207 var srcAppGUIDs []string 208 for _, app := range applications { 209 srcAppGUIDs = append(srcAppGUIDs, app.GUID) 210 } 211 212 v1Policies, err := actor.NetworkingClient.ListPolicies(srcAppGUIDs...) 213 if err != nil { 214 return []Policy{}, allWarnings, err 215 } 216 217 // ListPolicies will return policies with the app guids in either the source or destination. 218 // It needs to be further filtered to only get policies with the app guids in the source. 219 v1Policies = filterPoliciesWithoutMatchingSourceGUIDs(v1Policies, srcAppGUIDs) 220 221 destAppGUIDs := uniqueDestGUIDs(v1Policies) 222 223 destApplications, warnings, err := actor.V3Actor.GetApplicationsByGUIDs(destAppGUIDs...) 224 allWarnings = append(allWarnings, warnings...) 225 if err != nil { 226 return []Policy{}, allWarnings, err 227 } 228 229 applications = append(applications, destApplications...) 230 spaceGUIDs := uniqueSpaceGUIDs(applications) 231 232 spaces, warnings, err := actor.V3Actor.GetSpacesByGUIDs(spaceGUIDs...) 233 allWarnings = append(allWarnings, warnings...) 234 if err != nil { 235 return []Policy{}, allWarnings, err 236 } 237 238 spaceNamesByGUID := make(map[string]string, len(spaces)) 239 for _, destSpace := range spaces { 240 spaceNamesByGUID[destSpace.GUID] = destSpace.Name 241 } 242 243 orgNamesBySpaceGUID, warnings, err := actor.orgNamesBySpaceGUID(spaces) 244 allWarnings = append(allWarnings, warnings...) 245 if err != nil { 246 return []Policy{}, allWarnings, err 247 } 248 249 appByGUID := map[string]v3action.Application{} 250 for _, app := range applications { 251 appByGUID[app.GUID] = app 252 } 253 254 var policies []Policy 255 for _, v1Policy := range v1Policies { 256 destination := appByGUID[v1Policy.Destination.ID] 257 policies = append(policies, Policy{ 258 SourceName: appByGUID[v1Policy.Source.ID].Name, 259 DestinationName: destination.Name, 260 Protocol: string(v1Policy.Destination.Protocol), 261 StartPort: v1Policy.Destination.Ports.Start, 262 EndPort: v1Policy.Destination.Ports.End, 263 DestinationSpaceName: spaceNamesByGUID[destination.SpaceGUID], 264 DestinationOrgName: orgNamesBySpaceGUID[destination.SpaceGUID], 265 }) 266 } 267 268 return policies, allWarnings, nil 269 }