@@ -18,6 +18,8 @@ import (
1818	"github.com/sapcc/andromeda/models" 
1919)
2020
21+ var  errEntityPendingDeletion  =  errors .New ("this entity has been marked as either PENDING_DELETE or DELETED and therefore must be excluded from the AS3 declaration" )
22+ 
2123type  as3CommonTenantBuilderFunc  func (s  AndromedaF5Store , datacenters  []* rpcmodels.Datacenter , domains  []* rpcmodels.Domain ) (
2224	as3.Tenant , []* server.ProvisioningStatusRequest_ProvisioningStatus , error )
2325
@@ -51,25 +53,67 @@ func buildAS3Declaration(f5Config config.F5Config, s AndromedaF5Store, ctbFunc a
5153	// build all /domain_{domainID} keys 
5254	for  _ , domain  :=  range  domains  {
5355		domainTenant , domainTenantRPCUpdates , err  :=  dtbFunc (f5Config , datacentersByID , domain )
54- 		if  err  !=  nil  {
56+ 		// not a soft error: the declaration cannot be built 
57+ 		if  err  !=  nil  &&  err  !=  errEntityPendingDeletion  {
5558			return  adc , rpcRequest , err 
5659		}
60+ 		// only the active domains may be included in the declaration. 
61+ 		// domains pending deletion are excluded (and thus deleted by AS3). 
62+ 		if  err  !=  errEntityPendingDeletion  {
63+ 			adc .AddTenant (as3DeclarationGSLBDomainTenantKey (domain .Id ), domainTenant )
64+ 		}
5765		rpcUpdates  =  append (rpcUpdates , domainTenantRPCUpdates ... )
58- 		adc .AddTenant (as3DeclarationGSLBDomainTenantKey (domain .Id ), domainTenant )
5966	}
6067	rpcRequest .ProvisioningStatus  =  rpcUpdates 
6168	return  adc , rpcRequest , nil 
6269}
6370
71+ // buildAS3DomainTenant builds one domain tenant ("domain_{domainID}" keys of AS3 declaration). 
72+ // 
73+ // If the given domain has been either scheduled for deletion or marked as 
74+ // deleted, the returned tenant (first return value) should be considered a 
75+ // zero value to be discarded. This condition can be checked for by comparing 
76+ // the return error (third return value) to errEntityPendingDeletion. 
77+ // 
78+ // In case the domain provisioning status is set as PENDING_DELETE, the 
79+ // returned slice of provisioning status requests will include an entry for 
80+ // this domain, which shall be sent over RPC to the Andromeda Server 
81+ // immediately after the next successful posting of the AS3 declaration. 
6482func  buildAS3DomainTenant (
6583	f5Config  config.F5Config ,
6684	datacentersByID  map [string ]* rpcmodels.Datacenter ,
6785	domain  * rpcmodels.Domain ) (as3.Tenant , []* server.ProvisioningStatusRequest_ProvisioningStatus , error ) {
6886	tenant  :=  as3.Tenant {}
6987	rpcUpdates  :=  []* server.ProvisioningStatusRequest_ProvisioningStatus {}
88+ 	switch  domain .ProvisioningStatus  {
89+ 	case  server .ProvisioningStatusRequest_ProvisioningStatus_DELETED .String (),
90+ 		server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String ():
91+ 		if  domain .ProvisioningStatus  ==  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String () {
92+ 			rpcUpdates  =  append (rpcUpdates , & server.ProvisioningStatusRequest_ProvisioningStatus {
93+ 				Id :     domain .Id ,
94+ 				Model :  server .ProvisioningStatusRequest_ProvisioningStatus_DOMAIN ,
95+ 				Status : server .ProvisioningStatusRequest_ProvisioningStatus_DELETED ,
96+ 			})
97+ 		}
98+ 		// by excluding the entity from the AS3 declaration the API will delete it from the F5 device 
99+ 		return  tenant , rpcUpdates , errEntityPendingDeletion 
100+ 	}
70101	application  :=  as3.Application {}
71102	as3PoolReferences  :=  []as3.PointerGSLBPool {}
72103	for  _ , p  :=  range  domain .Pools  {
104+ 		switch  p .ProvisioningStatus  {
105+ 		case  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String (),
106+ 			server .ProvisioningStatusRequest_ProvisioningStatus_DELETED .String ():
107+ 			if  p .ProvisioningStatus  ==  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String () {
108+ 				rpcUpdates  =  append (rpcUpdates , & server.ProvisioningStatusRequest_ProvisioningStatus {
109+ 					Id :     p .Id ,
110+ 					Model :  server .ProvisioningStatusRequest_ProvisioningStatus_POOL ,
111+ 					Status : server .ProvisioningStatusRequest_ProvisioningStatus_DELETED ,
112+ 				})
113+ 			}
114+ 			// by excluding the entity from the AS3 declaration the API will delete it from the F5 device 
115+ 			continue 
116+ 		}
73117		rpcUpdates  =  append (rpcUpdates , & server.ProvisioningStatusRequest_ProvisioningStatus {
74118			Id :     p .Id ,
75119			Model :  server .ProvisioningStatusRequest_ProvisioningStatus_POOL ,
@@ -132,6 +176,19 @@ func buildAS3CommonTenant(
132176		for  _ , pool  :=  range  domain .Pools  {
133177			monitorsByPoolID [pool .Id ] =  pool .Monitors 
134178			for  _ , monitor  :=  range  pool .Monitors  {
179+ 				switch  monitor .ProvisioningStatus  {
180+ 				case  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String (),
181+ 					server .ProvisioningStatusRequest_ProvisioningStatus_DELETED .String ():
182+ 					if  monitor .ProvisioningStatus  ==  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String () {
183+ 						rpcUpdates  =  append (rpcUpdates , & server.ProvisioningStatusRequest_ProvisioningStatus {
184+ 							Id :     monitor .Id ,
185+ 							Model :  server .ProvisioningStatusRequest_ProvisioningStatus_MONITOR ,
186+ 							Status : server .ProvisioningStatusRequest_ProvisioningStatus_DELETED ,
187+ 						})
188+ 					}
189+ 					// by excluding the entity from the AS3 declaration the API will delete it from the F5 device 
190+ 					continue 
191+ 				}
135192				monitorKey  :=  as3DeclarationGSLBMonitorKey (monitor .Id )
136193				application .SetEntity (monitorKey , as3.GSLBMonitor {
137194					Class :        "GSLB_Monitor" ,
@@ -156,9 +213,28 @@ func buildAS3CommonTenant(
156213			return  tenant , rpcUpdates , err 
157214		}
158215		for  _ , member  :=  range  members  {
216+ 			switch  member .ProvisioningStatus  {
217+ 			case  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String (),
218+ 				server .ProvisioningStatusRequest_ProvisioningStatus_DELETED .String ():
219+ 				if  member .ProvisioningStatus  ==  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String () {
220+ 					rpcUpdates  =  append (rpcUpdates , & server.ProvisioningStatusRequest_ProvisioningStatus {
221+ 						Id :     member .Id ,
222+ 						Model :  server .ProvisioningStatusRequest_ProvisioningStatus_MEMBER ,
223+ 						Status : server .ProvisioningStatusRequest_ProvisioningStatus_DELETED ,
224+ 					})
225+ 				}
226+ 				// by excluding the entity from the AS3 declaration the API will delete it from the F5 device 
227+ 				continue 
228+ 			}
159229			monitorPointers  :=  []as3.PointerGSLBMonitor {}
160230			if  monitors , ok  :=  monitorsByPoolID [member .PoolId ]; ok  {
161231				for  _ , monitor  :=  range  monitors  {
232+ 					switch  monitor .ProvisioningStatus  {
233+ 					case  server .ProvisioningStatusRequest_ProvisioningStatus_PENDING_DELETE .String (),
234+ 						server .ProvisioningStatusRequest_ProvisioningStatus_DELETED .String ():
235+ 						// these monitors are not part of the declaration (see GSLB_Monitor setup above) 
236+ 						continue 
237+ 					}
162238					monitorPointers  =  append (monitorPointers , as3.PointerGSLBMonitor {
163239						Use : as3DeclarationGSLBMonitorKey (monitor .Id ),
164240					})
0 commit comments