44 "encoding/json"
55 "errors"
66 "fmt"
7- "github.com/xeipuuv/gojsonschema"
87 "io/ioutil"
98 "log"
109 "net/http"
@@ -13,9 +12,10 @@ import (
1312 "strconv"
1413 "strings"
1514 "time"
15+
16+ "github.com/xeipuuv/gojsonschema"
1617)
1718
18- const as3SchemaLatestURL = "https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/master/schema/latest/as3-schema.json"
1919const doSchemaLatestURL = "https://raw.githubusercontent.com/F5Networks/terraform-provider-bigip/master/schemas/doschema.json"
2020
2121const (
@@ -28,11 +28,6 @@ const (
2828 uriAsyncDeclare = "declare?async=true"
2929)
3030
31- type as3Validate struct {
32- as3SchemaURL string
33- as3SchemaLatest string
34- }
35-
3631type doValidate struct {
3732 doSchemaURL string
3833 doSchemaLatest string
@@ -45,66 +40,6 @@ type as3Version struct {
4540 SchemaMinimum string `json:"schemaMinimum"`
4641}
4742
48- func ValidateAS3Template (as3ExampleJson string ) bool {
49- myAs3 := & as3Validate {
50- as3SchemaLatestURL ,
51- "" ,
52- }
53- err := myAs3 .fetchAS3Schema ()
54- if err != nil {
55- fmt .Errorf ("As3 Schema Fetch failed: %s" , err )
56- return false
57- }
58-
59- schemaLoader := gojsonschema .NewStringLoader (myAs3 .as3SchemaLatest )
60- documentLoader := gojsonschema .NewStringLoader (as3ExampleJson )
61-
62- result , err := gojsonschema .Validate (schemaLoader , documentLoader )
63- if err != nil {
64- fmt .Errorf ("%s" , err )
65- return false
66- }
67- if ! result .Valid () {
68- log .Printf ("The document is not valid. see errors :\n " )
69- for _ , desc := range result .Errors () {
70- log .Printf ("- %s\n " , desc )
71- }
72- return false
73- }
74- return true
75- }
76-
77- func (as3 * as3Validate ) fetchAS3Schema () error {
78- res , resErr := http .Get (as3 .as3SchemaURL )
79- if resErr != nil {
80- log .Printf ("Error while fetching latest as3 schema : %v" , resErr )
81- return resErr
82- }
83- if res .StatusCode == http .StatusOK {
84- body , err := ioutil .ReadAll (res .Body )
85- if err != nil {
86- log .Printf ("Unable to read the as3 template from json response body : %v" , err )
87- return err
88- }
89- defer res .Body .Close ()
90- jsonMap := make (map [string ]interface {})
91- err = json .Unmarshal (body , & jsonMap )
92- if err != nil {
93- log .Printf ("Unable to unmarshal json response body : %v" , err )
94- return err
95- }
96- jsonMap ["$id" ] = as3SchemaLatestURL
97- byteJSON , err := json .Marshal (jsonMap )
98- if err != nil {
99- log .Printf ("Unable to marshal : %v" , err )
100- return err
101- }
102- as3 .as3SchemaLatest = string (byteJSON )
103- return err
104- }
105- return nil
106- }
107-
10843func ValidateDOTemplate (doExampleJson string ) bool {
10944 myDO := & doValidate {
11045 doSchemaLatestURL ,
@@ -173,6 +108,9 @@ type Results1 struct {
173108 RunTime int64 `json:"runTime,omitempty"`
174109}
175110
111+ /*
112+ PostAs3Bigip used for posting as3 json file to BIGIP
113+ */
176114func (b * BigIP ) PostAs3Bigip (as3NewJson string , tenantFilter string ) (error , string ) {
177115 tenant := tenantFilter + "?async=true"
178116 successfulTenants := make ([]string , 0 )
@@ -183,46 +121,50 @@ func (b *BigIP) PostAs3Bigip(as3NewJson string, tenantFilter string) (error, str
183121 respRef := make (map [string ]interface {})
184122 json .Unmarshal (resp , & respRef )
185123 respID := respRef ["id" ].(string )
186- taskStatus , err := b .getas3Taskstatus (respID )
187- respCode := taskStatus . Results [ 0 ].Code
188- log .Printf ("[DEBUG]Code = %v,ID = %v" , respCode , respID )
124+ taskStatus , err := b .getas3TaskStatus (respID )
125+ respCode := taskStatus [ "results" ].([] interface {})[ 0 ].( map [ string ] interface {})[ "code" ].( float64 )
126+ log .Printf ("[DEBUG]Code = %+ v,ID = %+ v" , respCode , respID )
189127 for respCode != 200 {
190- fastTask , err := b .getas3Taskstatus (respID )
128+ fastTask , err := b .getas3TaskStatus (respID )
191129 if err != nil {
192130 return err , ""
193131 }
194- respCode = fastTask . Results [ 0 ].Code
132+ respCode = fastTask [ "results" ].([] interface {})[ 0 ].( map [ string ] interface {})[ "code" ].( float64 )
195133 if respCode != 0 && respCode != 503 {
196- tenant_list , tenant_count := b .GetTenantList (as3NewJson )
134+ tenant_list , tenant_count , _ := b .GetTenantList (as3NewJson )
197135 if tenantCompare (tenant_list , tenantFilter ) == 1 {
136+ if len (fastTask ["results" ].([]interface {})) == 1 && fastTask ["results" ].([]interface {})[0 ].(map [string ]interface {})["message" ].(string ) == "declaration is invalid" {
137+ return fmt .Errorf ("Tenant Creation failed with :%+v" , fastTask ["results" ].([]interface {})[0 ].(map [string ]interface {})["errors" ]), ""
138+ }
198139 i := tenant_count - 1
199140 success_count := 0
200141 for i >= 0 {
201- if fastTask . Results [ i ].Code == 200 {
202- successfulTenants = append (successfulTenants , fastTask . Results [ i ].Tenant )
142+ if fastTask [ "results" ].([] interface {})[ i ].( map [ string ] interface {})[ "code" ].( float64 ) == 200 {
143+ successfulTenants = append (successfulTenants , fastTask [ "results" ].([] interface {})[ i ].( map [ string ] interface {})[ "tenant" ].( string ) )
203144 success_count ++
204145 }
205- if fastTask . Results [ i ].Code >= 400 {
206- log .Printf ("[ERROR] : HTTP %d :: %s for tenant %v" , fastTask . Results [ i ].Code , fastTask . Results [ i ].Message , fastTask . Results [ i ].Tenant )
146+ if fastTask [ "results" ].([] interface {})[ i ].( map [ string ] interface {})[ "code" ].( float64 ) >= 400 {
147+ log .Printf ("[ERROR] : HTTP %v :: %s for tenant %v" , fastTask [ "results" ].([] interface {})[ i ].( map [ string ] interface {})[ "code" ].( float64 ) , fastTask [ "results" ].([] interface {})[ i ].( map [ string ] interface {})[ "message" ].( string ) , fastTask [ "results" ].([] interface {})[ i ].( map [ string ] interface {})[ "tenant" ] )
207148 }
208149 i = i - 1
209150 }
210151 if success_count == tenant_count {
211152 log .Printf ("[DEBUG]Sucessfully Created Application with ID = %v" , respID )
212153 break // break here
213154 } else if success_count == 0 {
214- return errors . New ( fmt .Sprintf ("Tenant Creation failed" ) ), ""
155+ return fmt .Errorf ("Tenant Creation failed" ), ""
215156 } else {
216157 finallist := strings .Join (successfulTenants [:], "," )
217- return errors .New (fmt .Sprintf ("Partial Success" )), finallist
158+ j , _ := json .MarshalIndent (fastTask ["results" ].([]interface {}), "" , "\t " )
159+ return fmt .Errorf ("as3 config post error response %+v" , string (j )), finallist
218160 }
219161 }
220162 if respCode == 200 {
221163 log .Printf ("[DEBUG]Sucessfully Created Application with ID = %v" , respID )
222164 break // break here
223165 }
224166 if respCode >= 400 {
225- return errors . New ( fmt .Sprintf ("Tenant Creation failed" ) ), ""
167+ return fmt .Errorf ("Tenant Creation failed" ), ""
226168 }
227169 }
228170 if respCode == 503 {
@@ -242,46 +184,6 @@ func (b *BigIP) PostAs3Bigip(as3NewJson string, tenantFilter string) (error, str
242184 return nil , strings .Join (successfulTenants [:], "," )
243185}
244186
245- /*func (b *BigIP) DeleteAs3Bigip(tenantName string) error {
246- tenant := tenantName + "?async=true"
247- resp, err := b.deleteReq(uriMgmt, uriShared, uriAppsvcs, uriDeclare, tenant)
248- if err != nil {
249- return err
250- }
251- respRef := make(map[string]interface{})
252- json.Unmarshal(resp, &respRef)
253- respID := respRef["id"].(string)
254- taskStatus, err := b.getas3Taskstatus(respID)
255- respCode := taskStatus.Results[0].Code
256- log.Printf("[DEBUG]Delete Code = %v,ID = %v", respCode, respID)
257- for respCode != 200 {
258- fastTask, err := b.getas3Taskstatus(respID)
259- if err != nil {
260- return err
261- }
262- respCode = fastTask.Results[0].Code
263- if respCode == 200 {
264- log.Printf("[DEBUG]Sucessfully Deleted Application with ID = %v", respID)
265- break // break here
266- }
267- if respCode == 503 {
268- taskIds, err := b.getas3Taskid()
269- if err != nil {
270- return err
271- }
272- for _, id := range taskIds {
273- if b.pollingStatus(id) {
274- return b.DeleteAs3Bigip(tenantName)
275- }
276- }
277- }
278- time.Sleep(3 * time.Second)
279- }
280-
281- return nil
282-
283- }*/
284-
285187func (b * BigIP ) DeleteAs3Bigip (tenantName string ) (error , string ) {
286188 tenant := tenantName + "?async=true"
287189 failedTenants := make ([]string , 0 )
@@ -388,7 +290,7 @@ func (b *BigIP) ModifyAs3(tenantFilter string, as3_json string) error {
388290 return nil
389291
390292}
391- func (b * BigIP ) GetAs3 (name string ) (string , error ) {
293+ func (b * BigIP ) GetAs3 (name , appList string ) (string , error ) {
392294 as3Json := make (map [string ]interface {})
393295 as3Json ["class" ] = "AS3"
394296 as3Json ["action" ] = "deploy"
@@ -406,6 +308,37 @@ func (b *BigIP) GetAs3(name string) (string, error) {
406308 as3Json ["declaration" ] = adcJson
407309 out , _ := json .Marshal (as3Json )
408310 as3String := string (out )
311+ tenantList := strings .Split (appList , "," )
312+ found := 0
313+ for _ , item := range tenantList {
314+ if item == "Shared" {
315+ found = 1
316+ }
317+ }
318+ if found == 0 {
319+ sharedTenant := ""
320+ resp := []byte (as3String )
321+ jsonRef := make (map [string ]interface {})
322+ json .Unmarshal (resp , & jsonRef )
323+ for key , value := range jsonRef {
324+ if rec , ok := value .(map [string ]interface {}); ok && key == "declaration" {
325+ for k , v := range rec {
326+ if rec2 , ok := v .(map [string ]interface {}); ok {
327+ for k1 , v1 := range rec2 {
328+ if _ , ok := v1 .(map [string ]interface {}); ok {
329+ if k1 == "Shared" {
330+ sharedTenant = k
331+ }
332+ }
333+ }
334+ }
335+ delete (rec , sharedTenant )
336+ }
337+ }
338+ }
339+ out , _ = json .Marshal (jsonRef )
340+ as3String = string (out )
341+ }
409342 return as3String , nil
410343}
411344func (b * BigIP ) getAs3version () (* as3Version , error ) {
@@ -423,7 +356,14 @@ func (b *BigIP) getas3Taskstatus(id string) (*As3TaskType, error) {
423356 return nil , err
424357 }
425358 return & taskList , nil
426-
359+ }
360+ func (b * BigIP ) getas3TaskStatus (id string ) (map [string ]interface {}, error ) {
361+ var taskList map [string ]interface {}
362+ err , _ := b .getForEntity (& taskList , uriMgmt , uriShared , uriAppsvcs , uriTask , id )
363+ if err != nil {
364+ return nil , err
365+ }
366+ return taskList , nil
427367}
428368func (b * BigIP ) getas3Taskid () ([]string , error ) {
429369 var taskList As3AllTaskType
@@ -454,8 +394,9 @@ func (b *BigIP) pollingStatus(id string) bool {
454394 }
455395 return true
456396}
457- func (b * BigIP ) GetTenantList (body interface {}) (string , int ) {
458- s := make ([]string , 0 )
397+ func (b * BigIP ) GetTenantList (body interface {}) (string , int , string ) {
398+ tenantList := make ([]string , 0 )
399+ applicationList := make ([]string , 0 )
459400 as3json := body .(string )
460401 resp := []byte (as3json )
461402 jsonRef := make (map [string ]interface {})
@@ -469,16 +410,29 @@ func (b *BigIP) GetTenantList(body interface{}) (string, int) {
469410 if k1 == "class" && v1 == "Tenant" {
470411 found = 1
471412 }
413+ if rec3 , ok := v1 .(map [string ]interface {}); ok {
414+ found1 := 0
415+ for k2 , v2 := range rec3 {
416+ if k2 == "class" && v2 == "Application" {
417+ found1 = 1
418+ }
419+ }
420+ if found1 == 1 {
421+ applicationList = append (applicationList , k1 )
422+ }
423+
424+ }
472425 }
473426 if found == 1 {
474- s = append (s , k )
427+ tenantList = append (tenantList , k )
475428 }
476429 }
477430 }
478431 }
479432 }
480- tenant_list := strings .Join (s [:], "," )
481- return tenant_list , len (s )
433+ finalTenantlist := strings .Join (tenantList [:], "," )
434+ finalApplicationList := strings .Join (applicationList [:], "," )
435+ return finalTenantlist , len (tenantList ), finalApplicationList
482436}
483437func (b * BigIP ) AddTeemAgent (body interface {}) (string , error ) {
484438 var s string
0 commit comments