55 "log"
66 "regexp"
77 "strconv"
8+ "strings"
89
910 "github.com/f5devcentral/go-bigip"
1011 "github.com/hashicorp/terraform/helper/schema"
@@ -38,7 +39,7 @@ func resourceBigipLtmVirtualServer() *schema.Resource {
3839 "source" : {
3940 Type : schema .TypeString ,
4041 Optional : true ,
41- Default : "0.0.0.0/0" ,
42+ Computed : true ,
4243 Description : "Source IP and mask for the virtual server" ,
4344 },
4445
@@ -57,7 +58,7 @@ func resourceBigipLtmVirtualServer() *schema.Resource {
5758 "mask" : {
5859 Type : schema .TypeString ,
5960 Optional : true ,
60- Default : "255.255.255.255" ,
61+ Computed : true ,
6162 Description : "Mask can either be in CIDR notation or decimal, i.e.: \" 24\" or \" 255.255.255.0\" . A CIDR mask of \" 0\" is the same as \" 0.0.0.0\" " ,
6263 },
6364
@@ -162,9 +163,36 @@ func resourceBigipLtmVirtualServer() *schema.Resource {
162163 }
163164}
164165
166+ func resourceBigipLtmVirtualServerAttrDefaults (d * schema.ResourceData ) {
167+ _ , hasMask := d .GetOk ("mask" )
168+ _ , hasSource := d .GetOk ("source" )
169+
170+ // Set default mask if nil
171+ if ! hasMask {
172+ // looks like IPv6, lets set to /128
173+ if strings .Contains (d .Get ("destination" ).(string ), ":" ) {
174+ d .Set ("mask" , "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" )
175+ } else { // /32 for IPv4
176+ d .Set ("mask" , "255.255.255.255" )
177+ }
178+ }
179+
180+ // set default source if nil
181+ if ! hasSource {
182+ // looks like IPv6, lets set to ::/0
183+ if strings .Contains (d .Get ("destination" ).(string ), ":" ) {
184+ d .Set ("source" , "::/0" )
185+ } else { // 0.0.0.0/0
186+ d .Set ("source" , "0.0.0.0/0" )
187+ }
188+ }
189+ }
190+
165191func resourceBigipLtmVirtualServerCreate (d * schema.ResourceData , meta interface {}) error {
166192 client := meta .(* bigip.BigIP )
167193
194+ resourceBigipLtmVirtualServerAttrDefaults (d )
195+
168196 name := d .Get ("name" ).(string )
169197 port := d .Get ("port" ).(int )
170198 TranslateAddress := d .Get ("translate_port" ).(string )
@@ -215,18 +243,36 @@ func resourceBigipLtmVirtualServerRead(d *schema.ResourceData, meta interface{})
215243 return nil
216244 }
217245 // Extract destination address from "/partition_name/(virtual_server_address)[%route_domain]:port"
218- regex := regexp .MustCompile (`(\/.+\/)((?:[0-9]{1,3}\.){3}[0-9]{1,3})(?:\%\d+)?(\: \d+)` )
246+ regex := regexp .MustCompile (`(\/.+\/)((?:[0-9]{1,3}\.){3}[0-9]{1,3})(?:\%\d+)?(?:\:( \d+) )` )
219247 destination := regex .FindStringSubmatch (vs .Destination )
220- if len (destination ) < 3 {
221- return fmt .Errorf ("Unable to extract destination address from virtual server destination: " + vs .Destination )
248+ if destination == nil {
249+ // We should try a IPv6 extraction
250+
251+ regex = regexp .MustCompile (`^(\/.+\/)(.*:[^%]*)(?:\%\d+)?(?:\.(\d+))$` )
252+ destination = regex .FindStringSubmatch (vs .Destination )
253+
254+ if destination == nil {
255+ return fmt .Errorf ("Unable to extract destination address and port from virtual server destination: " + vs .Destination )
256+ }
222257 }
258+
223259 if err := d .Set ("destination" , destination [2 ]); err != nil {
224260 return fmt .Errorf ("[DEBUG] Error saving Destination to state for Virtual Server (%s): %s" , d .Id (), err )
225261 }
226262
227263 // Extract source address from "(source_address)[%route_domain](/mask)" groups 1 + 2
228264 regex = regexp .MustCompile (`((?:[0-9]{1,3}\.){3}[0-9]{1,3})(?:\%\d+)?(\/\d+)` )
229265 source := regex .FindStringSubmatch (vs .Source )
266+ if source == nil {
267+ // We should try a IPv6 extraction
268+
269+ regex = regexp .MustCompile (`^(.*:[^%]*)(?:\%\d+)?(\/\d+)$` )
270+ source = regex .FindStringSubmatch (vs .Source )
271+
272+ if source == nil {
273+ return fmt .Errorf ("Unable to extract source address and mask from virtual server destination: " + vs .Source )
274+ }
275+ }
230276 parsedSource := source [1 ] + source [2 ]
231277 if err := d .Set ("source" , parsedSource ); err != nil {
232278 return fmt .Errorf ("[DEBUG] Error saving Source to state for Virtual Server (%s): %s" , d .Id (), err )
@@ -241,15 +287,8 @@ func resourceBigipLtmVirtualServerRead(d *schema.ResourceData, meta interface{})
241287 return fmt .Errorf ("[DEBUG] Error saving Mask to state for Virtual Server (%s): %s" , d .Id (), err )
242288 }
243289
244- /* Service port is provided by the API in the destination attribute "/partition_name/virtual_server_address[%route_domain]:(port)"
245- so we need to extract it
246- */
247- regex = regexp .MustCompile (`\:(\d+)` )
248- port := regex .FindStringSubmatch (vs .Destination )
249- if len (port ) < 2 {
250- return fmt .Errorf ("Unable to extract service port from virtual server destination: %s" , vs .Destination )
251- }
252- parsedPort , _ := strconv .Atoi (port [1 ])
290+ // Service port was extracted earlier
291+ parsedPort , _ := strconv .Atoi (destination [3 ])
253292 d .Set ("port" , parsedPort )
254293
255294 d .Set ("irules" , makeStringList (& vs .Rules ))
@@ -330,6 +369,8 @@ func resourceBigipLtmVirtualServerExists(d *schema.ResourceData, meta interface{
330369func resourceBigipLtmVirtualServerUpdate (d * schema.ResourceData , meta interface {}) error {
331370 client := meta .(* bigip.BigIP )
332371
372+ resourceBigipLtmVirtualServerAttrDefaults (d )
373+
333374 name := d .Id ()
334375
335376 var profiles []bigip.Profile
@@ -371,8 +412,13 @@ func resourceBigipLtmVirtualServerUpdate(d *schema.ResourceData, meta interface{
371412 rules = listToStringSlice (cfg_rules .([]interface {}))
372413 }
373414
415+ destPort := fmt .Sprintf ("%s:%d" , d .Get ("destination" ).(string ), d .Get ("port" ).(int ))
416+ if strings .Contains (d .Get ("destination" ).(string ), ":" ) {
417+ destPort = fmt .Sprintf ("%s.%d" , d .Get ("destination" ).(string ), d .Get ("port" ).(int ))
418+ }
419+
374420 vs := & bigip.VirtualServer {
375- Destination : fmt . Sprintf ( "%s:%d" , d . Get ( "destination" ).( string ), d . Get ( "port" ).( int )) ,
421+ Destination : destPort ,
376422 FallbackPersistenceProfile : d .Get ("fallback_persistence_profile" ).(string ),
377423 Source : d .Get ("source" ).(string ),
378424 Pool : d .Get ("pool" ).(string ),
0 commit comments