diff --git a/client/client.go b/client/client.go index 7e3c1da..f85d191 100644 --- a/client/client.go +++ b/client/client.go @@ -174,7 +174,7 @@ func (c *Client) MakeRestRequest(method string, path string, body *container.Con return nil, err } req.Header.Set("Content-Type", "application/json") - log.Printf("HTTP request %s %s", method, path) + log.Printf("[DEBUG] HTTP request %s %s", method, path) if authenticated { @@ -183,7 +183,7 @@ func (c *Client) MakeRestRequest(method string, path string, body *container.Con return req, err } } - log.Printf("HTTP request after injection %s %s", method, path) + log.Printf("[DEBUG] HTTP request after injection %s %s", method, path) return req, nil } @@ -301,12 +301,13 @@ func (c *Client) Do(req *http.Request) (*container.Container, *http.Response, er if err != nil { return nil, nil, err } - log.Printf("nHTTP Response: %d %s %v", resp.StatusCode, resp.Status, resp) + log.Printf("[DEBUG] HTTP Request: %s %s", req.Method, req.URL.String()) + log.Printf("[DEBUG] HTTP Response: %d %s %v", resp.StatusCode, resp.Status, resp) bodyBytes, err := ioutil.ReadAll(resp.Body) bodyStr := string(bodyBytes) resp.Body.Close() - log.Printf("\n HTTP response unique string %s %s %s", req.Method, req.URL.String(), bodyStr) + log.Printf("[DEBUG] HTTP response unique string %s %s %s", req.Method, req.URL.String(), bodyStr) if req.Method != "DELETE" && resp.StatusCode != 204 { obj, err := container.ParseJSON(bodyBytes) diff --git a/client/client_service.go b/client/client_service.go index eaeb1ec..09df48c 100644 --- a/client/client_service.go +++ b/client/client_service.go @@ -3,6 +3,7 @@ package client import ( "errors" "fmt" + "log" "net/url" "github.com/ciscoecosystem/mso-go-client/container" @@ -119,7 +120,7 @@ func (c *Client) PatchbyID(endpoint string, objList ...models.Model) (*container contJs.ArrayAppend(jsonPayload.Data()) } - + log.Printf("[DEBUG] Patch Request Container: %v\n", contJs) // URL encoding baseUrl, _ := url.Parse(endpoint) qs := url.Values{} diff --git a/client/dhcp_option_policy_option_service.go b/client/dhcp_option_policy_option_service.go new file mode 100644 index 0000000..e0eb4af --- /dev/null +++ b/client/dhcp_option_policy_option_service.go @@ -0,0 +1,132 @@ +package client + +import ( + "fmt" + "strings" + + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) CreateDHCPOptionPolicyOption(obj *models.DHCPOptionPolicyOption) error { + optionPolicyID, err := client.GetDHCPOptionPolicyID(obj.PolicyName) + if err != nil { + return err + } + optionPolicyCont, err := client.ReadDHCPOptionPolicy(optionPolicyID) + if err != nil { + return err + } + DHCPOptionPolicy, err := models.DHCPOptionPolicyFromContainer(optionPolicyCont) + if err != nil { + return err + } + option := models.DHCPOption{ + Data: obj.Data, + ID: obj.ID, + Name: obj.Name, + } + DHCPOptionPolicy.DHCPOption = append(DHCPOptionPolicy.DHCPOption, option) + _, err = client.UpdateDHCPOptionPolicy(optionPolicyID, DHCPOptionPolicy) + if err != nil { + return err + } + return nil +} + +func (client *Client) ReadDHCPOptionPolicyOption(id string) (*models.DHCPOptionPolicyOption, error) { + idSplit := strings.Split(id, "/") + optionPolicyID, err := client.GetDHCPOptionPolicyID(idSplit[0]) + if err != nil { + return nil, err + } + optionPolicyCont, err := client.ReadDHCPOptionPolicy(optionPolicyID) + if err != nil { + return nil, err + } + DHCPOptionPolicy, err := models.DHCPOptionPolicyFromContainer(optionPolicyCont) + if err != nil { + return nil, err + } + flag := false + dhcpOption := models.DHCPOptionPolicyOption{} + for _, option := range DHCPOptionPolicy.DHCPOption { + if option.Name == idSplit[1] { + flag = true + dhcpOption.Name = option.Name + dhcpOption.ID = option.ID + dhcpOption.Data = option.Data + dhcpOption.PolicyName = DHCPOptionPolicy.Name + break + } + } + if flag { + return &dhcpOption, nil + } + + return nil, fmt.Errorf("No DHCP Option Policy found") +} + +func (client *Client) UpdateDHCPOptionPolicyOption(obj *models.DHCPOptionPolicyOption) error { + optionPolicyID, err := client.GetDHCPOptionPolicyID(obj.PolicyName) + if err != nil { + return err + } + optionPolicyCont, err := client.ReadDHCPOptionPolicy(optionPolicyID) + if err != nil { + return err + } + DHCPOptionPolicy, err := models.DHCPOptionPolicyFromContainer(optionPolicyCont) + if err != nil { + return err + } + NewOptions := make([]models.DHCPOption, 0, 1) + NewOption := models.DHCPOption{ + Data: obj.Data, + ID: obj.ID, + Name: obj.Name, + } + + for _, option := range DHCPOptionPolicy.DHCPOption { + if option.Name != obj.Name { + NewOptions = append(NewOptions, option) + } else { + NewOptions = append(NewOptions, NewOption) + } + } + DHCPOptionPolicy.DHCPOption = NewOptions + _, err = client.UpdateDHCPOptionPolicy(optionPolicyID, DHCPOptionPolicy) + if err != nil { + return err + } + return nil +} + +func (client *Client) DeleteDHCPOptionPolicyOption(id string) error { + idSplit := strings.Split(id, "/") + optionPolicyID, err := client.GetDHCPOptionPolicyID(idSplit[0]) + if err != nil { + return err + } + optionPolicyCont, err := client.ReadDHCPOptionPolicy(optionPolicyID) + if err != nil { + return err + } + DHCPOptionPolicy, err := models.DHCPOptionPolicyFromContainer(optionPolicyCont) + if err != nil { + return err + } + NewOptions := make([]models.DHCPOption, 0, 1) + for _, option := range DHCPOptionPolicy.DHCPOption { + if option.Name == idSplit[1] { + option.ID = "remove" + } + NewOptions = append(NewOptions, option) + } + DHCPOptionPolicy.DHCPOption = NewOptions + _, err = client.UpdateDHCPOptionPolicy(optionPolicyID, DHCPOptionPolicy) + if err != nil { + return err + } + + return nil +} diff --git a/client/dhcp_option_policy_service.go b/client/dhcp_option_policy_service.go new file mode 100644 index 0000000..239dbc7 --- /dev/null +++ b/client/dhcp_option_policy_service.go @@ -0,0 +1,70 @@ +package client + +import ( + "fmt" + + "github.com/ciscoecosystem/mso-go-client/container" + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) GetDHCPOptionPolicyID(name string) (string, error) { + path := "api/v1/policies/dhcp/option" + cont, err := client.GetViaURL(path) + if err != nil { + return "", err + } + for _, policy := range cont.S("DhcpRelayPolicies").Data().([]interface{}) { + if optionPol, ok := policy.(map[string]interface{}); ok { + if name == optionPol["name"].(string) { + return optionPol["id"].(string), nil + } + } + } + return "", fmt.Errorf("DHCP Option Policy with name: %s not found", name) +} + +func (client *Client) CreateDHCPOptionPolicy(obj *models.DHCPOptionPolicy) (*container.Container, error) { + path := "api/v1/policies/dhcp/option" + cont, err := client.Save(path, obj) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) ReadDHCPOptionPolicy(id string) (*container.Container, error) { + path := "api/v1/policies/dhcp/option/" + id + cont, err := client.GetViaURL(path) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) UpdateDHCPOptionPolicy(id string, obj *models.DHCPOptionPolicy) (*container.Container, error) { + remotePolicy, err := client.ReadDHCPOptionPolicy(id) + if err != nil { + return nil, err + } + + payloadModel, err := models.PrepareDHCPOptionPolicyModelForUpdate(remotePolicy, obj) + if err != nil { + return nil, err + } + + path := "api/v1/policies/dhcp/option/" + id + cont, err := client.Put(path, payloadModel) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) DeleteDHCPOptionPolicy(id string) error { + path := "api/v1/policies/dhcp/option/" + id + err := client.DeletebyId(path) + if err != nil { + return err + } + return nil +} diff --git a/client/dhcp_relay_policy_provider_service.go b/client/dhcp_relay_policy_provider_service.go new file mode 100644 index 0000000..f7b9e4e --- /dev/null +++ b/client/dhcp_relay_policy_provider_service.go @@ -0,0 +1,123 @@ +package client + +import ( + "fmt" + + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) CreateDHCPRelayPolicyProvider(obj *models.DHCPRelayPolicyProvider) error { + relayPolicyId, err := client.GetDHCPRelayPolicyID(obj.PolicyName) + if err != nil { + return err + } + relayPolicyCont, err := client.ReadDHCPRelayPolicy(relayPolicyId) + if err != nil { + return err + } + DHCPRelay, err := models.DHCPRelayPolicyFromContainer(relayPolicyCont) + if err != nil { + return err + } + provider := models.DHCPProvider{ + ExternalEPG: obj.ExternalEpgRef, + EPG: obj.EpgRef, + DHCPServerAddress: obj.Addr, + TenantID: DHCPRelay.TenantID, + } + DHCPRelay.DHCPProvider = append(DHCPRelay.DHCPProvider, provider) + _, err = client.UpdateDHCPRelayPolicy(relayPolicyId, DHCPRelay) + if err != nil { + return err + } + return nil +} + +func (client *Client) UpdateDHCPRelayPolicyProvider(new *models.DHCPRelayPolicyProvider, old *models.DHCPRelayPolicyProvider) error { + relayPolicyId, err := client.GetDHCPRelayPolicyID(old.PolicyName) + if err != nil { + return err + } + relayPolicyCont, err := client.ReadDHCPRelayPolicy(relayPolicyId) + if err != nil { + return err + } + DHCPRelay, err := models.DHCPRelayPolicyFromContainer(relayPolicyCont) + if err != nil { + return err + } + NewProviders := make([]models.DHCPProvider, 0, 1) + NewProvider := models.DHCPProvider{ + ExternalEPG: new.ExternalEpgRef, + EPG: new.EpgRef, + DHCPServerAddress: new.Addr, + TenantID: DHCPRelay.TenantID, + } + for _, provider := range DHCPRelay.DHCPProvider { + if provider.DHCPServerAddress != old.Addr && provider.EPG != old.EpgRef && old.ExternalEpgRef != new.ExternalEpgRef { + NewProviders = append(NewProviders, provider) + } else { + NewProviders = append(NewProviders, NewProvider) + } + } + DHCPRelay.DHCPProvider = NewProviders + _, err = client.UpdateDHCPRelayPolicy(relayPolicyId, DHCPRelay) + if err != nil { + return err + } + return nil +} + +func (client *Client) DeleteDHCPRelayPolicyProvider(obj *models.DHCPRelayPolicyProvider) error { + relayPolicyId, err := client.GetDHCPRelayPolicyID(obj.PolicyName) + if err != nil { + return err + } + relayPolicyCont, err := client.ReadDHCPRelayPolicy(relayPolicyId) + if err != nil { + return err + } + DHCPRelay, err := models.DHCPRelayPolicyFromContainer(relayPolicyCont) + if err != nil { + return err + } + NewProviders := make([]models.DHCPProvider, 0, 1) + for _, provider := range DHCPRelay.DHCPProvider { + if provider.DHCPServerAddress == obj.Addr && provider.EPG == obj.EpgRef && provider.ExternalEPG == obj.ExternalEpgRef { + provider.Operation = "remove" + } + NewProviders = append(NewProviders, provider) + } + DHCPRelay.DHCPProvider = NewProviders + _, err = client.UpdateDHCPRelayPolicy(relayPolicyId, DHCPRelay) + if err != nil { + return err + } + return nil +} + +func (client *Client) ReadDHCPRelayPolicyProvider(obj *models.DHCPRelayPolicyProvider) (*models.DHCPRelayPolicyProvider, error) { + relayPolicyId, err := client.GetDHCPRelayPolicyID(obj.PolicyName) + if err != nil { + return nil, err + } + relayPolicyCont, err := client.ReadDHCPRelayPolicy(relayPolicyId) + if err != nil { + return nil, err + } + DHCPRelay, err := models.DHCPRelayPolicyFromContainer(relayPolicyCont) + if err != nil { + return nil, err + } + flag := false + for _, provider := range DHCPRelay.DHCPProvider { + if provider.DHCPServerAddress == obj.Addr && provider.EPG == obj.EpgRef && provider.ExternalEPG == obj.ExternalEpgRef { + flag = true + break + } + } + if flag { + return obj, nil + } + return nil, fmt.Errorf("no DHCP Relay Policy found") +} diff --git a/client/dhcp_relay_policy_service.go b/client/dhcp_relay_policy_service.go new file mode 100644 index 0000000..5715872 --- /dev/null +++ b/client/dhcp_relay_policy_service.go @@ -0,0 +1,69 @@ +package client + +import ( + "fmt" + + "github.com/ciscoecosystem/mso-go-client/container" + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) GetDHCPRelayPolicyID(name string) (string, error) { + path := "api/v1/policies/dhcp/relay" + cont, err := client.GetViaURL(path) + if err != nil { + return "", err + } + for _, policy := range cont.S("DhcpRelayPolicies").Data().([]interface{}) { + if relayPol, ok := policy.(map[string]interface{}); ok { + if name == relayPol["name"].(string) { + return relayPol["id"].(string), nil + } + } + } + return "", fmt.Errorf("DHCP Relay Policy with name: %s not found", name) +} + +func (client *Client) CreateDHCPRelayPolicy(obj *models.DHCPRelayPolicy) (*container.Container, error) { + path := "api/v1/policies/dhcp/relay" + cont, err := client.Save(path, obj) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) ReadDHCPRelayPolicy(id string) (*container.Container, error) { + path := "api/v1/policies/dhcp/relay/" + id + cont, err := client.GetViaURL(path) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) UpdateDHCPRelayPolicy(id string, obj *models.DHCPRelayPolicy) (*container.Container, error) { + remotePolicy, err := client.ReadDHCPRelayPolicy(id) + if err != nil { + return nil, err + } + + payloadModel, err := models.PrepareDHCPRelayPolicyModelForUpdate(remotePolicy, obj) + if err != nil { + return nil, err + } + path := "api/v1/policies/dhcp/relay/" + id + cont, err := client.Put(path, payloadModel) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) DeleteDHCPRelayPolicy(id string) error { + path := "api/v1/policies/dhcp/relay/" + id + err := client.DeletebyId(path) + if err != nil { + return err + } + return nil +} diff --git a/client/schema_site_anp_epg_useg_attr_service.go b/client/schema_site_anp_epg_useg_attr_service.go new file mode 100644 index 0000000..dee54f2 --- /dev/null +++ b/client/schema_site_anp_epg_useg_attr_service.go @@ -0,0 +1,55 @@ +package client + +import ( + "fmt" + "sync" + + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) CreateAnpEpgUsegAttr(obj *models.SiteUsegAttr) error { + useg := models.SiteAnpEpgUsegAttrForCreation(obj) + _, err := client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), useg) + if err != nil { + return err + } + return nil +} + +func (client *Client) DeleteAnpEpgUsegAttr(obj *models.SiteUsegAttr) error { + _, useg_index, read_err := client.ReadAnpEpgUsegAttr(obj) + if read_err != nil { + return read_err + } + useg := models.SiteAnpEpgUsegAttrforDeletion(obj, useg_index) + _, err := client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), useg) + if err != nil { + return err + } + return nil +} + +func (client *Client) UpdateAnpEpgUsegAttr(obj *models.SiteUsegAttr) error { + _, useg_index, read_err := client.ReadAnpEpgUsegAttr(obj) + if read_err != nil { + return read_err + } + useg := models.SiteAnpEpgUsegAttrforUpdate(obj, useg_index) + _, err := client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), useg) + if err != nil { + return err + } + return nil +} + +func (client *Client) ReadAnpEpgUsegAttr(obj *models.SiteUsegAttr) (*models.SiteUsegAttr, int, error) { + schemaCont, err := client.GetViaURL(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID)) + if err != nil { + return nil, -1, err + } + useg, useg_index, err := models.SiteAnpEpgUsegAttrFromContainer(schemaCont, obj) + if err != nil { + return nil, -1, err + } + return useg, useg_index, nil +} diff --git a/client/schema_site_l3_out_service.go b/client/schema_site_l3_out_service.go new file mode 100644 index 0000000..ed907e8 --- /dev/null +++ b/client/schema_site_l3_out_service.go @@ -0,0 +1,38 @@ +package client + +import ( + "fmt" + "sync" + + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) CreateIntersiteL3outs(obj *models.IntersiteL3outs) error { + l3out := models.CreateIntersiteL3outsModel(obj) + _, err := client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), l3out) + if err != nil { + return err + } + return nil +} + +func (client *Client) DeleteIntersiteL3outs(obj *models.IntersiteL3outs) error { + l3out := models.DeleteIntersiteL3outsModel(obj) + _, err := client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), l3out) + if err != nil { + return err + } + return nil +} + +func (client *Client) ReadIntersiteL3outs(obj *models.IntersiteL3outs) (*models.IntersiteL3outs, error) { + schemaCont, err := client.GetViaURL(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID)) + if err != nil { + return nil, err + } + l3out, err := models.IntersiteL3outsFromContainer(schemaCont, obj) + if err != nil { + return nil, err + } + return l3out, nil +} diff --git a/client/schema_site_vrf_region_hub_network_service.go b/client/schema_site_vrf_region_hub_network_service.go new file mode 100644 index 0000000..b611140 --- /dev/null +++ b/client/schema_site_vrf_region_hub_network_service.go @@ -0,0 +1,52 @@ +package client + +import ( + "fmt" + "sync" + + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) CreateInterSchemaSiteVrfRegionHubNetwork(obj *models.InterSchemaSiteVrfRegionHubNetork) error { + schemaCont, err := client.GetViaURL(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID)) + if err != nil { + return err + } + hubNetwork, err := models.CreateInterSchemaSiteVrfRegionNetworkModel(obj, schemaCont) + if err != nil { + return err + } + _, err = client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), hubNetwork) + if err != nil { + return err + } + return nil +} + +func (client *Client) DeleteInterSchemaSiteVrfRegionHubNetwork(obj *models.InterSchemaSiteVrfRegionHubNetork) error { + schemaCont, err := client.GetViaURL(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID)) + if err != nil { + return err + } + hubNetwork, err := models.DeleteInterSchemaSiteVrfRegionNetworkModel(obj, schemaCont) + if err != nil { + return err + } + _, err = client.PatchbyID(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID), hubNetwork) + if err != nil { + return err + } + return nil +} + +func (client *Client) ReadInterSchemaSiteVrfRegionHubNetwork(obj *models.InterSchemaSiteVrfRegionHubNetork) (*models.InterSchemaSiteVrfRegionHubNetork, error) { + schemaCont, err := client.GetViaURL(fmt.Sprintf("api/v1/schemas/%s", obj.SchemaID)) + if err != nil { + return nil, err + } + hubNetwork, err := models.InterSchemaSiteVrfRegionHubNetworkFromContainer(schemaCont, obj) + if err != nil { + return nil, err + } + return hubNetwork, nil +} diff --git a/client/schema_template_bd_dhcp_policy_service.go b/client/schema_template_bd_dhcp_policy_service.go new file mode 100644 index 0000000..eb5db22 --- /dev/null +++ b/client/schema_template_bd_dhcp_policy_service.go @@ -0,0 +1,42 @@ +package client + +import ( + "github.com/ciscoecosystem/mso-go-client/container" + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) CreateTemplateBDDHCPPolicy(obj *models.TemplateBDDHCPPolicy) (*container.Container, error) { + path := "api/v1/schemas/" + obj.SchemaID + cont, err := client.PatchbyID(path, models.TemplateBDDHCPPolicyModelForCreation(obj)) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) ReadTemplateBDDHCPPolicy(schemaID string) (*container.Container, error) { + path := "api/v1/schemas/" + schemaID + cont, err := client.GetViaURL(path) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) UpdateTemplateBDDHCPPolicy(obj *models.TemplateBDDHCPPolicy) (*container.Container, error) { + path := "api/v1/schemas/" + obj.SchemaID + cont, err := client.PatchbyID(path, models.TemplateBDDHCPPolicyModelForUpdate(obj)) + if err != nil { + return nil, err + } + return cont, nil +} + +func (client *Client) DeleteTemplateBDDHCPPolicy(obj *models.TemplateBDDHCPPolicy) (*container.Container, error) { + path := "api/v1/schemas/" + obj.SchemaID + cont, err := client.PatchbyID(path, models.TemplateBDDHCPPolicyModelForDeletion(obj)) + if err != nil { + return nil, CheckForErrors(cont, "PATCH") + } + return cont, nil +} diff --git a/client/schema_validate_service.go b/client/schema_validate_service.go new file mode 100644 index 0000000..6d6aff8 --- /dev/null +++ b/client/schema_validate_service.go @@ -0,0 +1,42 @@ +package client + +import ( + "errors" + "fmt" + + "github.com/ciscoecosystem/mso-go-client/container" + "github.com/ciscoecosystem/mso-go-client/models" +) + +func (client *Client) ReadSchemaValidate(obj *models.SchemValidate) (*models.SchemValidate, error) { + cont, err := client.GetSchemaValidate(fmt.Sprintf("api/v1/schemas/%s/validate", obj.SchmaId)) + if err != nil { + return nil, err + } + remoteSchemaValidate := models.SchemValidate{ + SchmaId: obj.SchmaId, + Result: models.G(cont, "result"), + } + return &remoteSchemaValidate, nil +} + +func (c *Client) GetSchemaValidate(endpoint string) (*container.Container, error) { + + req, err := c.MakeRestRequest("GET", endpoint, nil, true) + + if err != nil { + return nil, err + } + req.Header.Del("Content-Type") + + obj, _, err := c.Do(req) + if err != nil { + return nil, err + } + + if obj == nil { + return nil, errors.New("empty response body") + } + return obj, CheckForErrors(obj, "GET") + +} diff --git a/container/gabs.go b/container/gabs.go index 37356b0..c575438 100644 --- a/container/gabs.go +++ b/container/gabs.go @@ -27,6 +27,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "io" "io/ioutil" "strings" @@ -577,3 +578,29 @@ func ParseJSONBuffer(buffer io.Reader) (*Container, error) { } //-------------------------------------------------------------------------------------------------- + +func (g *Container) SearchInObjectList(condition func(*Container) bool) (*Container, error) { + children, err := g.Children() + if err != nil { + return nil, err + } + for _, obj := range children { + if condition(obj) { + return obj, nil + } + } + return nil, fmt.Errorf("Object Not found") +} + +func (g *Container) SearchInObjectListWithIndex(condition func(*Container) bool) (*Container, int, error) { + children, err := g.Children() + if err != nil { + return nil, -1, err + } + for index, obj := range children { + if condition(obj) { + return obj, index, nil + } + } + return nil, -1, fmt.Errorf("Object Not found") +} diff --git a/models/dhcp_option_policy.go b/models/dhcp_option_policy.go new file mode 100644 index 0000000..11e07d8 --- /dev/null +++ b/models/dhcp_option_policy.go @@ -0,0 +1,86 @@ +package models + +import ( + "encoding/json" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type DHCPOptionPolicy struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + PolicyType string `json:"policyType,omitempty"` + PolicySubtype string `json:"policySubtype,omitempty"` + Desc string `json:"desc"` + TenantID string `json:"tenantId"` + DHCPOption []DHCPOption `json:"dhcpOption"` +} + +func NewDHCPOptionPolicy(policy DHCPOptionPolicy) *DHCPOptionPolicy { + newDHCPOptionPolicy := policy + return &newDHCPOptionPolicy +} + +type DHCPOption struct { + ID string `json:"id"` + Name string `json:"name"` + Data string `json:"data"` +} + +func (model *DHCPOptionPolicy) ToMap() (map[string]interface{}, error) { + objMap := make(map[string]interface{}) + + jsonObj, err := json.Marshal(model) + if err != nil { + return nil, err + } + + err = json.Unmarshal(jsonObj, &objMap) + if err != nil { + return nil, err + } + + return objMap, nil +} + +func DHCPOptionPolicyFromContainer(cont *container.Container) (*DHCPOptionPolicy, error) { + policy := DHCPOptionPolicy{} + + err := json.Unmarshal(cont.EncodeJSON(), &policy) + if err != nil { + return nil, err + } + + return &policy, nil +} + +func PrepareDHCPOptionPolicyModelForUpdate(remotePolicyCont *container.Container, newPolicy *DHCPOptionPolicy) (*DHCPOptionPolicy, error) { + remotePolicy := DHCPOptionPolicy{} + err := json.Unmarshal(remotePolicyCont.Bytes(), &remotePolicy) + if err != nil { + return nil, err + } + + newOptionList := make([]DHCPOption, 0) + + for _, newOption := range newPolicy.DHCPOption { + if newOption.ID != "remove" { + newOptionList = append(newOptionList, newOption) + } + } + + for _, remoteOption := range remotePolicy.DHCPOption { + found := false + for _, newOption := range newPolicy.DHCPOption { + if newOption.Name == remoteOption.Name { + found = true + } + } + if !found { + newOptionList = append(newOptionList, remoteOption) + } + } + + newPolicy.DHCPOption = newOptionList + return newPolicy, nil +} diff --git a/models/dhcp_option_policy_option.go b/models/dhcp_option_policy_option.go new file mode 100644 index 0000000..f3aeabc --- /dev/null +++ b/models/dhcp_option_policy_option.go @@ -0,0 +1,25 @@ +package models + +import ( + "encoding/json" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type DHCPOptionPolicyOption struct { + ID string + Name string + Data string + PolicyName string +} + +func DHCPOptionPolicyOptionFromContainer(cont *container.Container) (*DHCPOptionPolicyOption, error) { + option := DHCPOptionPolicyOption{} + + err := json.Unmarshal(cont.EncodeJSON(), &option) + if err != nil { + return nil, err + } + + return &option, nil +} diff --git a/models/dhcp_relay_policy_provider.go b/models/dhcp_relay_policy_provider.go new file mode 100644 index 0000000..25f9862 --- /dev/null +++ b/models/dhcp_relay_policy_provider.go @@ -0,0 +1,8 @@ +package models + +type DHCPRelayPolicyProvider struct { + PolicyName string + Addr string + EpgRef string + ExternalEpgRef string +} diff --git a/models/label.go b/models/label.go index e0637b6..574f60d 100644 --- a/models/label.go +++ b/models/label.go @@ -1,22 +1,17 @@ package models type Label struct { - Id string `json:",omitempty"` + Id string `json:",omitempty"` DisplayName string `json:",omitempty"` - Type string `json:",omitempty"` + Type string `json:",omitempty"` } +func NewLabel(id, labels, types string) *Label { - - -func NewLabel (id, labels, types string) *Label{ - return &Label{ - Id: id, + Id: id, DisplayName: labels, - Type: types, - - + Type: types, } } @@ -26,7 +21,5 @@ func (label *Label) ToMap() (map[string]interface{}, error) { A(labelAttributeMap, "displayName", label.DisplayName) A(labelAttributeMap, "type", label.Type) - - return labelAttributeMap, nil -} \ No newline at end of file +} diff --git a/models/relay_policy.go b/models/relay_policy.go new file mode 100644 index 0000000..741f45f --- /dev/null +++ b/models/relay_policy.go @@ -0,0 +1,86 @@ +package models + +import ( + "encoding/json" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type DHCPRelayPolicy struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + PolicyType string `json:"policyType,omitempty"` + PolicySubtype string `json:"policySubtype,omitempty"` + Desc string `json:"desc"` + TenantID string `json:"tenantId"` + DHCPProvider []DHCPProvider `json:"provider"` +} + +func NewDHCPRelayPolicy(policy DHCPRelayPolicy) *DHCPRelayPolicy { + newDHCPRelayPolicy := policy + return &newDHCPRelayPolicy +} + +type DHCPProvider struct { + ExternalEPG string `json:"externalEpgRef"` + EPG string `json:"epgRef"` + DHCPServerAddress string `json:"addr"` + TenantID string `json:"tenantId"` + Operation string `json:"-"` +} + +func (model *DHCPRelayPolicy) ToMap() (map[string]interface{}, error) { + objMap := make(map[string]interface{}) + + jsonObj, err := json.Marshal(model) + if err != nil { + return nil, err + } + + err = json.Unmarshal(jsonObj, &objMap) + if err != nil { + return nil, err + } + + return objMap, nil +} + +func DHCPRelayPolicyFromContainer(cont *container.Container) (*DHCPRelayPolicy, error) { + policy := DHCPRelayPolicy{} + err := json.Unmarshal(cont.EncodeJSON(), &policy) + if err != nil { + return nil, err + } + return &policy, nil +} + +func PrepareDHCPRelayPolicyModelForUpdate(remotePolicyCont *container.Container, newPolicy *DHCPRelayPolicy) (*DHCPRelayPolicy, error) { + remotePolicy := DHCPRelayPolicy{} + err := json.Unmarshal(remotePolicyCont.Bytes(), &remotePolicy) + if err != nil { + return nil, err + } + + newProviderList := make([]DHCPProvider, 0) + + for _, newProvider := range newPolicy.DHCPProvider { + if newProvider.Operation != "remove" { + newProviderList = append(newProviderList, newProvider) + } + } + + for _, remoteProvider := range remotePolicy.DHCPProvider { + found := false + for _, newProvider := range newPolicy.DHCPProvider { + if remoteProvider.DHCPServerAddress == newProvider.DHCPServerAddress && remoteProvider.EPG == newProvider.EPG && remoteProvider.ExternalEPG == newProvider.ExternalEPG { + found = true + } + } + if !found { + newProviderList = append(newProviderList, remoteProvider) + } + } + + newPolicy.DHCPProvider = newProviderList + return newPolicy, nil +} diff --git a/models/schema_site_anp.go b/models/schema_site_anp.go index 50b5d86..e3b3ffe 100644 --- a/models/schema_site_anp.go +++ b/models/schema_site_anp.go @@ -9,8 +9,8 @@ type SiteAnp struct { func NewSchemaSiteAnp(ops, path string, anpRef map[string]interface{}) *SiteAnp { var externalepgMap map[string]interface{} externalepgMap = map[string]interface{}{ - "anpRef": anpRef, - "epgs": []interface{}{}, + "anpRef": anpRef, + "epgs": []interface{}{}, } return &SiteAnp{ diff --git a/models/schema_site_anp_epg_staticleaf.go b/models/schema_site_anp_epg_staticleaf.go index 0e064d5..ad92856 100644 --- a/models/schema_site_anp_epg_staticleaf.go +++ b/models/schema_site_anp_epg_staticleaf.go @@ -6,11 +6,11 @@ type SiteAnpEpgStaticLeaf struct { Value map[string]interface{} `json:",omitempty"` } -func NewSchemaSiteAnpEpgStaticleaf(ops, path , paths string, port int) *SiteAnpEpgStaticLeaf { +func NewSchemaSiteAnpEpgStaticleaf(ops, path, paths string, port int) *SiteAnpEpgStaticLeaf { var externalepgMap map[string]interface{} externalepgMap = map[string]interface{}{ - "path": paths, - "portEncapVlan":port, + "path": paths, + "portEncapVlan": port, } return &SiteAnpEpgStaticLeaf{ @@ -30,4 +30,4 @@ func (externalepgAttributes *SiteAnpEpgStaticLeaf) ToMap() (map[string]interface } return externalepgAttributesMap, nil -} \ No newline at end of file +} diff --git a/models/schema_site_anp_epg_useg_attr.go b/models/schema_site_anp_epg_useg_attr.go new file mode 100644 index 0000000..ce92719 --- /dev/null +++ b/models/schema_site_anp_epg_useg_attr.go @@ -0,0 +1,193 @@ +package models + +import ( + "fmt" + "regexp" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type SiteAnpEpgUsegAttr struct { + Ops string `json:",omitempty"` + Path string `json:",omitempty"` + Value map[string]interface{} `json:",omitempty"` +} + +type SiteUsegAttr struct { + SchemaID string + TemplateName string + SiteID string + AnpName string + EpgName string + UsegName string + Description string + Type string + Operator string + Category string + Value string + FvSubnet bool +} + +func SiteAnpEpgUsegAttrForCreation(useg *SiteUsegAttr) *SiteAnpEpgUsegAttr { + siteAnpEpgUsegAttr := SiteAnpEpgUsegAttr{ + Ops: "add", + Path: fmt.Sprintf("/sites/%s-%s/anps/%s/epgs/%s/uSegAttrs/-", useg.SiteID, useg.TemplateName, useg.AnpName, useg.EpgName), + } + + usegAttr := map[string]interface{}{ + "name": useg.UsegName, + "displayName": useg.UsegName, + "type": useg.Type, + "value": useg.Value, + } + + if StringInSlice(useg.Type, []string{"tag", "domain", "guest-os", "hv", "rootContName", "vm", "vm-name", "vnic"}) { + usegAttr["operator"] = useg.Operator + } + + if useg.Type == "tag" { + usegAttr["category"] = useg.Category + } + + if useg.Description != "" { + usegAttr["description"] = useg.Description + } + + if useg.Type == "ip" && useg.FvSubnet == true { + usegAttr["fvSubnet"] = useg.FvSubnet + usegAttr["value"] = "0.0.0.0" + } else if useg.Type == "ip" { + usegAttr["fvSubnet"] = useg.FvSubnet + } + + siteAnpEpgUsegAttr.Value = usegAttr + return &siteAnpEpgUsegAttr +} + +func SiteAnpEpgUsegAttrforDeletion(useg *SiteUsegAttr, index int) *SiteAnpEpgUsegAttr { + siteAnpEpgUsegAttr := SiteAnpEpgUsegAttr{ + Ops: "remove", + Path: fmt.Sprintf("/sites/%s-%s/anps/%s/epgs/%s/uSegAttrs/%d", useg.SiteID, useg.TemplateName, useg.AnpName, useg.EpgName, index), + } + return &siteAnpEpgUsegAttr +} + +func SiteAnpEpgUsegAttrforUpdate(useg *SiteUsegAttr, index int) *SiteAnpEpgUsegAttr { + siteAnpEpgUsegAttr := SiteAnpEpgUsegAttr{ + Ops: "replace", + Path: fmt.Sprintf("/sites/%s-%s/anps/%s/epgs/%s/uSegAttrs/%d", useg.SiteID, useg.TemplateName, useg.AnpName, useg.EpgName, index), + } + + usegAttr := map[string]interface{}{ + "name": useg.UsegName, + "displayName": useg.UsegName, + "type": useg.Type, + "value": useg.Value, + } + + if StringInSlice(useg.Type, []string{"tag", "domain", "guest-os", "hv", "rootContName", "vm", "vm-name"}) { + usegAttr["operator"] = useg.Operator + } + + if useg.Type == "tag" { + usegAttr["category"] = useg.Category + } + + if useg.Description != "" { + usegAttr["description"] = useg.Description + } + + if useg.Type == "ip" && useg.FvSubnet == true { + usegAttr["fvSubnet"] = useg.FvSubnet + usegAttr["value"] = "0.0.0.0" + } else if useg.Type == "ip" { + usegAttr["fvSubnet"] = useg.FvSubnet + } + + siteAnpEpgUsegAttr.Value = usegAttr + return &siteAnpEpgUsegAttr +} + +func SiteAnpEpgUsegAttrFromContainer(cont *container.Container, tf *SiteUsegAttr) (*SiteUsegAttr, int, error) { + siteUsegAttr := SiteUsegAttr{} + siteUsegAttr.SchemaID = tf.SchemaID + siteUsegAttr.SiteID = tf.SiteID + siteUsegAttr.TemplateName = tf.TemplateName + siteCont, err := cont.S("sites").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "siteId") == tf.SiteID && G(cont, "templateName") == tf.TemplateName + }, + ) + if err != nil { + return nil, -1, err + } + + siteUsegAttr.AnpName = tf.AnpName + anpCont, err := siteCont.S("anps").SearchInObjectList( + func(cont *container.Container) bool { + anpRef := G(cont, "anpRef") + re := regexp.MustCompile("/schemas/(.*)/templates/(.*)/anps/(.*)") + match := re.FindStringSubmatch(anpRef) + anpName := match[3] + return anpName == tf.AnpName + }, + ) + if err != nil { + return nil, -1, err + } + + siteUsegAttr.EpgName = tf.EpgName + epgCont, err := anpCont.S("epgs").SearchInObjectList( + func(cont *container.Container) bool { + epgRef := G(cont, "epgRef") + re := regexp.MustCompile("/schemas/(.*)/templates/(.*)/epgs/(.*)") + match := re.FindStringSubmatch(epgRef) + epgName := match[3] + return epgName == tf.EpgName + }, + ) + if err != nil { + return nil, -1, err + } + + siteUsegAttr.UsegName = tf.UsegName + usegCont, useg_index, err := epgCont.S("uSegAttrs").SearchInObjectListWithIndex( + func(cont *container.Container) bool { + return G(cont, "name") == tf.UsegName + }, + ) + if err != nil { + return nil, -1, err + } + + siteUsegAttr.Type = G(usegCont, "type") + siteUsegAttr.Value = G(usegCont, "value") + + if StringInSlice(siteUsegAttr.Type, []string{"tag", "domain", "guest-os", "hv", "rootContName", "vm", "vm-name"}) { + siteUsegAttr.Operator = G(usegCont, "operator") + } + + if siteUsegAttr.Type == "tag" { + siteUsegAttr.Category = G(usegCont, "category") + } + + if usegCont.Exists("description") { + siteUsegAttr.Description = G(usegCont, "description") + } + + if siteUsegAttr.Type == "ip" && G(usegCont, "fvSubnet") == "true" { + siteUsegAttr.FvSubnet = true + } + + return &siteUsegAttr, useg_index, nil +} + +func (useg *SiteAnpEpgUsegAttr) ToMap() (map[string]interface{}, error) { + usegMap := make(map[string]interface{}) + A(usegMap, "op", useg.Ops) + A(usegMap, "path", useg.Path) + if useg.Value != nil { + A(usegMap, "value", useg.Value) + } + return usegMap, nil +} diff --git a/models/schema_site_bd.go b/models/schema_site_bd.go index 8645987..9d82da6 100644 --- a/models/schema_site_bd.go +++ b/models/schema_site_bd.go @@ -6,10 +6,10 @@ type SiteBd struct { Value map[string]interface{} `json:",omitempty"` } -func NewSchemaSiteBd(ops, path string, anpRef map[string]interface{},host bool) *SiteBd { +func NewSchemaSiteBd(ops, path string, anpRef map[string]interface{}, host bool) *SiteBd { var externalepgMap map[string]interface{} externalepgMap = map[string]interface{}{ - "bdRef": anpRef, + "bdRef": anpRef, "hostBasedRouting": host, } @@ -30,4 +30,4 @@ func (externalepgAttributes *SiteBd) ToMap() (map[string]interface{}, error) { } return externalepgAttributesMap, nil -} \ No newline at end of file +} diff --git a/models/schema_site_l3_out.go b/models/schema_site_l3_out.go new file mode 100644 index 0000000..ced7fe2 --- /dev/null +++ b/models/schema_site_l3_out.go @@ -0,0 +1,111 @@ +package models + +import ( + "fmt" + "strings" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type SiteL3Out struct { + Ops string `json:",omitempty"` + Path string `json:",omitempty"` + Value map[string]interface{} `json:",omitempty"` +} + +type IntersiteL3outs struct { + L3outName string + VRFName string + SchemaID string + TemplateName string + SiteId string +} + +func CreateIntersiteL3outsModel(l3out *IntersiteL3outs) *SiteL3Out { + site := SiteL3Out{ + Ops: "add", + Path: fmt.Sprintf("/sites/%s-%s/intersiteL3outs/-", l3out.SiteId, l3out.TemplateName), + } + sitemap := make(map[string]interface{}) + sitemap["l3outRef"] = map[string]string{ + "l3outName": l3out.L3outName, + "schemaId": l3out.SchemaID, + "templateName": l3out.TemplateName, + } + sitemap["vrfRef"] = map[string]string{ + "vrfName": l3out.VRFName, + "schemaId": l3out.SchemaID, + "templateName": l3out.TemplateName, + } + site.Value = sitemap + return &site +} + +func DeleteIntersiteL3outsModel(l3out *IntersiteL3outs) *SiteL3Out { + site := SiteL3Out{ + Ops: "remove", + Path: fmt.Sprintf("/sites/%s-%s/intersiteL3outs/%s", l3out.SiteId, l3out.TemplateName, l3out.L3outName), + } + sitemap := make(map[string]interface{}) + sitemap["l3outRef"] = map[string]string{ + "l3outName": l3out.L3outName, + "schemaId": l3out.SchemaID, + "templateName": l3out.TemplateName, + } + site.Value = sitemap + return &site +} + +func IntersiteL3outsFromContainer(cont *container.Container, tf *IntersiteL3outs) (*IntersiteL3outs, error) { + remoteL3out := IntersiteL3outs{} + var found bool = false + count, err := cont.ArrayCount("sites") + if err != nil { + return nil, fmt.Errorf("no Sites found") + } + for i := 0; i < count; i++ { + tempCont, err := cont.ArrayElement(i, "sites") + if err != nil { + return nil, err + } + apiSite := StripQuotes(tempCont.S("siteId").String()) + templateName := StripQuotes(tempCont.S("templateName").String()) + if apiSite == tf.SiteId && templateName == tf.TemplateName { + l3outCount, err := tempCont.ArrayCount("intersiteL3outs") + if err != nil { + return nil, fmt.Errorf("unable to get l3out list") + } + l3outCont := tempCont.S("intersiteL3outs") + for j := 0; j < l3outCount; j++ { + l3outTempCont := l3outCont.Index(j) + l3outRef := strings.Split(StripQuotes(l3outTempCont.S("l3outRef").String()), "/") + l3outName := l3outRef[len(l3outRef)-1] + vrfRef := strings.Split(StripQuotes(l3outTempCont.S("vrfRef").String()), "/") + vrfName := vrfRef[len(vrfRef)-1] + if l3outName == tf.L3outName && vrfName == tf.VRFName { + remoteL3out.L3outName = l3outName + remoteL3out.VRFName = vrfName + remoteL3out.SchemaID = l3outRef[2] + remoteL3out.SiteId = apiSite + remoteL3out.TemplateName = templateName + found = true + break + } + } + } + } + if !found { + return nil, fmt.Errorf("unable to find siteL3out %s", tf.L3outName) + } + return &remoteL3out, nil +} + +func (l3out *SiteL3Out) ToMap() (map[string]interface{}, error) { + l3outMap := make(map[string]interface{}) + A(l3outMap, "op", l3out.Ops) + A(l3outMap, "path", l3out.Path) + if l3out.Value != nil { + A(l3outMap, "value", l3out.Value) + } + return l3outMap, nil +} diff --git a/models/schema_site_vrf.go b/models/schema_site_vrf.go index 2afacff..9eb7b46 100644 --- a/models/schema_site_vrf.go +++ b/models/schema_site_vrf.go @@ -9,8 +9,8 @@ type SiteVrf struct { func NewSchemaSiteVrf(ops, path string, vrfRef map[string]interface{}) *SiteVrf { var externalepgMap map[string]interface{} externalepgMap = map[string]interface{}{ - "vrfRef": vrfRef, - "regions": []interface{}{}, + "vrfRef": vrfRef, + "regions": []interface{}{}, } return &SiteVrf{ @@ -30,4 +30,4 @@ func (externalepgAttributes *SiteVrf) ToMap() (map[string]interface{}, error) { } return externalepgAttributesMap, nil -} \ No newline at end of file +} diff --git a/models/schema_site_vrf_region_cidr_subnet.go b/models/schema_site_vrf_region_cidr_subnet.go index 3f1f8a9..678ba9d 100644 --- a/models/schema_site_vrf_region_cidr_subnet.go +++ b/models/schema_site_vrf_region_cidr_subnet.go @@ -10,9 +10,9 @@ func NewSchemaSiteVrfRegionCidrSubnet(ops, path, ip, zone, usage string) *Schema var bdsubnetMap map[string]interface{} if ops != "remove" { bdsubnetMap = map[string]interface{}{ - "ip": ip, - "zone": zone, - "usage": usage, + "ip": ip, + "zone": zone, + "usage": usage, } } else { bdsubnetMap = nil diff --git a/models/schema_site_vrf_region_hub_network.go b/models/schema_site_vrf_region_hub_network.go new file mode 100644 index 0000000..ef01f91 --- /dev/null +++ b/models/schema_site_vrf_region_hub_network.go @@ -0,0 +1,151 @@ +package models + +import ( + "encoding/json" + "fmt" + "regexp" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type SchemaSiteVrfRegionHubNetork struct { + Ops string `json:",omitempty"` + Path string `json:",omitempty"` + Value map[string]interface{} `json:",omitempty"` +} + +type InterSchemaSiteVrfRegionHubNetork struct { + Name string + TenantName string + SiteID string + TemplateName string + VrfName string + Region string + SchemaID string +} + +func CreateInterSchemaSiteVrfRegionNetworkModel(hubNetwork *InterSchemaSiteVrfRegionHubNetork, cont *container.Container) (*SchemaSiteVrfRegionHubNetork, error) { + vrfHubNetwork := SchemaSiteVrfRegionHubNetork{ + Ops: "replace", + Path: fmt.Sprintf("/sites/%s-%s/vrfs/%s/regions/%s", hubNetwork.SiteID, hubNetwork.TemplateName, hubNetwork.VrfName, hubNetwork.Region), + } + vrfRegionMap, err := InterSchemaSiteVrfRegionFromContainer(cont, hubNetwork) + if err != nil { + return nil, fmt.Errorf("No VRF Region found") + } + vrfRegionMap["cloudRsCtxProfileToGatewayRouterP"] = map[string]string{ + "name": hubNetwork.Name, + "tenantName": hubNetwork.TenantName, + } + vrfHubNetwork.Value = vrfRegionMap + return &vrfHubNetwork, nil +} + +func DeleteInterSchemaSiteVrfRegionNetworkModel(hubNetwork *InterSchemaSiteVrfRegionHubNetork, cont *container.Container) (*SchemaSiteVrfRegionHubNetork, error) { + vrfHubNetwork := SchemaSiteVrfRegionHubNetork{ + Ops: "replace", + Path: fmt.Sprintf("/sites/%s-%s/vrfs/%s/regions/%s", hubNetwork.SiteID, hubNetwork.TemplateName, hubNetwork.VrfName, hubNetwork.Region), + } + vrfHubNetworkMap := make(map[string]interface{}) + vrfHubNetworkMap["name"] = hubNetwork.Region + vrfRegionMap, err := InterSchemaSiteVrfRegionFromContainer(cont, hubNetwork) + if err != nil { + return nil, fmt.Errorf("No VRF Region found") + } + vrfRegionMap["cloudRsCtxProfileToGatewayRouterP"] = nil + vrfHubNetwork.Value = vrfRegionMap + return &vrfHubNetwork, nil +} + +func InterSchemaSiteVrfRegionFromContainer(cont *container.Container, regionHubNetwork *InterSchemaSiteVrfRegionHubNetork) (map[string]interface{}, error) { + regionMap := make(map[string]interface{}) + siteCont, err := cont.S("sites").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "siteId") == regionHubNetwork.SiteID && G(cont, "templateName") == regionHubNetwork.TemplateName + }, + ) + if err != nil { + return nil, err + } + vrfCont, err := siteCont.S("vrfs").SearchInObjectList( + func(cont *container.Container) bool { + vrfRef := G(cont, "vrfRef") + re := regexp.MustCompile("/schemas/(.*)/templates/(.*)/vrfs/(.*)") + match := re.FindStringSubmatch(vrfRef) + vrfName := match[3] + return vrfName == regionHubNetwork.VrfName + }, + ) + if err != nil { + return nil, err + } + regionCont, err := vrfCont.S("regions").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "name") == regionHubNetwork.Region + }, + ) + if err != nil { + return nil, err + } + err = json.Unmarshal(regionCont.EncodeJSON(), ®ionMap) + if err != nil { + return nil, err + } + return regionMap, nil +} + +func InterSchemaSiteVrfRegionHubNetworkFromContainer(cont *container.Container, regionHubNetwork *InterSchemaSiteVrfRegionHubNetork) (*InterSchemaSiteVrfRegionHubNetork, error) { + hubNetwork := InterSchemaSiteVrfRegionHubNetork{} + hubNetwork.SiteID = regionHubNetwork.SiteID + hubNetwork.TemplateName = regionHubNetwork.TemplateName + hubNetwork.SchemaID = regionHubNetwork.SchemaID + siteCont, err := cont.S("sites").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "siteId") == regionHubNetwork.SiteID && G(cont, "templateName") == regionHubNetwork.TemplateName + }, + ) + if err != nil { + return nil, err + } + hubNetwork.VrfName = regionHubNetwork.VrfName + vrfCont, err := siteCont.S("vrfs").SearchInObjectList( + func(cont *container.Container) bool { + vrfRef := G(cont, "vrfRef") + re := regexp.MustCompile("/schemas/(.*)/templates/(.*)/vrfs/(.*)") + match := re.FindStringSubmatch(vrfRef) + vrfName := match[3] + return vrfName == regionHubNetwork.VrfName + }, + ) + if err != nil { + return nil, err + } + hubNetwork.Region = regionHubNetwork.Region + regionCont, err := vrfCont.S("regions").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "name") == regionHubNetwork.Region + }, + ) + if err != nil { + return nil, err + } + hubNetwork.Name = regionHubNetwork.Name + hubNetwork.TenantName = regionHubNetwork.TenantName + if regionCont.Exists("cloudRsCtxProfileToGatewayRouterP") { + hubNetworkCont := regionCont.S("cloudRsCtxProfileToGatewayRouterP") + if G(hubNetworkCont, "name") == hubNetwork.Name && G(hubNetworkCont, "tenantName") == hubNetwork.TenantName { + return &hubNetwork, nil + } + } + return nil, fmt.Errorf("No Schema Site VRF Region Hub Network Found") +} + +func (hubNetwork *SchemaSiteVrfRegionHubNetork) ToMap() (map[string]interface{}, error) { + hubNetworkMap := make(map[string]interface{}) + A(hubNetworkMap, "op", hubNetwork.Ops) + A(hubNetworkMap, "path", hubNetwork.Path) + if hubNetwork.Value != nil { + A(hubNetworkMap, "value", hubNetwork.Value) + } + return hubNetworkMap, nil +} diff --git a/models/schema_template_anp.go b/models/schema_template_anp.go index fd00a9b..93b6aec 100644 --- a/models/schema_template_anp.go +++ b/models/schema_template_anp.go @@ -1,25 +1,23 @@ package models type SchemaTemplateAnp struct { - Ops string `json:",omitempty"` - Path string `json:",omitempty"` - Value map[string]interface{} `json:",omitempty"` - + Ops string `json:",omitempty"` + Path string `json:",omitempty"` + Value map[string]interface{} `json:",omitempty"` } -func NewSchemaTemplateAnp(ops, path, Name,displayName string) *SchemaTemplateAnp { +func NewSchemaTemplateAnp(ops, path, Name, displayName string) *SchemaTemplateAnp { var VrfMap map[string]interface{} - - if ops !="remove" { + + if ops != "remove" { VrfMap = map[string]interface{}{ - "displayName": displayName, - "name": Name, + "displayName": displayName, + "name": Name, "epgs": []interface{}{}, - } - }else{ - - VrfMap=nil + } else { + + VrfMap = nil } return &SchemaTemplateAnp{ @@ -39,4 +37,4 @@ func (schematemplateanpAttributes *SchemaTemplateAnp) ToMap() (map[string]interf } return schematemplateanpAttributeMap, nil -} \ No newline at end of file +} diff --git a/models/schema_template_anp_epg_subnet.go b/models/schema_template_anp_epg_subnet.go index e774270..6a771bb 100644 --- a/models/schema_template_anp_epg_subnet.go +++ b/models/schema_template_anp_epg_subnet.go @@ -1,24 +1,23 @@ package models type SchemaTemplateAnpEpgSubnet struct { - Ops string `json:",omitempty"` - Path string `json:",omitempty"` - Value map[string]interface{} `json:",omitempty"` - + Ops string `json:",omitempty"` + Path string `json:",omitempty"` + Value map[string]interface{} `json:",omitempty"` } -func NewSchemaTemplateAnpEpgSubnet(ops, path, ip,scope string,shared bool) *SchemaTemplateAnpEpgSubnet{ +func NewSchemaTemplateAnpEpgSubnet(ops, path, ip, scope string, shared bool) *SchemaTemplateAnpEpgSubnet { var SubnetMap map[string]interface{} - - if ops !="remove" { + + if ops != "remove" { SubnetMap = map[string]interface{}{ "ip": ip, - "scope": scope, - "shared": shared, + "scope": scope, + "shared": shared, } - }else{ - - SubnetMap=nil + } else { + + SubnetMap = nil } return &SchemaTemplateAnpEpgSubnet{ @@ -38,4 +37,4 @@ func (schematemplateanpepgsubnetAttributes *SchemaTemplateAnpEpgSubnet) ToMap() } return schematemplateanpepgsubnetAttributeMap, nil -} \ No newline at end of file +} diff --git a/models/schema_template_bd.go b/models/schema_template_bd.go index dc6f8cb..294377e 100644 --- a/models/schema_template_bd.go +++ b/models/schema_template_bd.go @@ -1,5 +1,11 @@ package models +type TemplateBD struct { + Ops string `json:",omitempty"` + Path string `json:",omitempty"` + Value map[string]interface{} `json:",omitempty"` +} + func NewTemplateBD(ops, path, name, displayName, layer2Unicast, unkMcastAct, multiDstPktAct, v6unkMcastAct, vmac string, intersiteBumTrafficAllow, optimizeWanBandwidth, l2Stretch, l3MCast, arpFlood, unicastRouting bool, vrfRef, dhcpLabel map[string]interface{}, dhcpLabels []interface{}) *PatchPayload { var bdMap map[string]interface{} bdMap = map[string]interface{}{ diff --git a/models/schema_template_bd_dhcp_policy.go b/models/schema_template_bd_dhcp_policy.go new file mode 100644 index 0000000..f6a73ed --- /dev/null +++ b/models/schema_template_bd_dhcp_policy.go @@ -0,0 +1,140 @@ +package models + +import ( + "fmt" + "strconv" + + "github.com/ciscoecosystem/mso-go-client/container" +) + +type TemplateBDDHCPPolicyOps struct { + Ops string `json:"op,omitempty"` + Path string `json:"path,omitempty"` + Value map[string]interface{} `json:"value,omitempty"` +} + +type TemplateBDDHCPPolicy struct { + Name string + Version int + DHCPOptionName string + DHCPOptionVersion int + BDName string + TemplateName string + SchemaID string +} + +func TemplateBDDHCPPolicyModelForCreation(bdDHCPPol *TemplateBDDHCPPolicy) *TemplateBDDHCPPolicyOps { + opsMap := TemplateBDDHCPPolicyOps{ + Ops: "add", + Path: fmt.Sprintf("/templates/%s/bds/%s/dhcpLabels/-", bdDHCPPol.TemplateName, bdDHCPPol.BDName), + } + opsVal := map[string]interface{}{ + "name": bdDHCPPol.Name, + "version": bdDHCPPol.Version, + } + + if bdDHCPPol.DHCPOptionName != "" { + opsVal["dhcpOptionLabel"] = map[string]interface{}{ + "name": bdDHCPPol.DHCPOptionName, + "version": func(v int) int { + if v == 0 { + return 1 + } + return v + }(bdDHCPPol.DHCPOptionVersion), + } + } + opsMap.Value = opsVal + return &opsMap +} + +func TemplateBDDHCPPolicyModelForUpdate(bdDHCPPol *TemplateBDDHCPPolicy) *TemplateBDDHCPPolicyOps { + opsMap := TemplateBDDHCPPolicyOps{ + Ops: "replace", + Path: fmt.Sprintf("/templates/%s/bds/%s/dhcpLabels/%s", bdDHCPPol.TemplateName, bdDHCPPol.BDName, bdDHCPPol.Name), + } + opsVal := map[string]interface{}{ + "name": bdDHCPPol.Name, + "version": bdDHCPPol.Version, + } + + if bdDHCPPol.DHCPOptionName != "" { + opsVal["dhcpOptionLabel"] = map[string]interface{}{ + "name": bdDHCPPol.DHCPOptionName, + "version": func(v int) int { + if v == 0 { + return 1 + } + return v + }(bdDHCPPol.DHCPOptionVersion), + } + } + opsMap.Value = opsVal + return &opsMap +} + +func TemplateBDDHCPPolicyModelForDeletion(bdDHCPPol *TemplateBDDHCPPolicy) *TemplateBDDHCPPolicyOps { + opsMap := TemplateBDDHCPPolicyOps{ + Ops: "remove", + Path: fmt.Sprintf("/templates/%s/bds/%s/dhcpLabels/%s", bdDHCPPol.TemplateName, bdDHCPPol.BDName, bdDHCPPol.Name), + } + return &opsMap +} + +func TemplateBDDHCPPolicyFromContainer(cont *container.Container, tf *TemplateBDDHCPPolicy) (*TemplateBDDHCPPolicy, error) { + remoteBDDHCPPol := TemplateBDDHCPPolicy{} + remoteBDDHCPPol.SchemaID = tf.SchemaID + remoteBDDHCPPol.TemplateName = tf.TemplateName + templateCont, err := cont.S("templates").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "name") == tf.TemplateName + }, + ) + if err != nil { + return nil, err + } + + remoteBDDHCPPol.BDName = tf.BDName + bdCont, err := templateCont.S("bds").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "name") == tf.BDName + }, + ) + if err != nil { + return nil, err + } + + bdDHCPCont, err := bdCont.S("dhcpLabels").SearchInObjectList( + func(cont *container.Container) bool { + return G(cont, "name") == tf.Name + }, + ) + if err != nil { + return nil, err + } + + remoteBDDHCPPol.Name = G(bdDHCPCont, "name") + remoteBDDHCPPol.Version, err = strconv.Atoi(G(bdDHCPCont, "version")) + if err != nil { + return nil, err + } + if bdDHCPCont.Exists("dhcpOptionLabel") { + remoteBDDHCPPol.DHCPOptionName = G(bdDHCPCont, "dhcpOptionLabel", "name") + remoteBDDHCPPol.DHCPOptionVersion, err = strconv.Atoi(G(bdDHCPCont, "dhcpOptionLabel", "version")) + if err != nil { + return nil, err + } + } + + return &remoteBDDHCPPol, nil +} + +func (templateBDDHCPPolicyOps *TemplateBDDHCPPolicyOps) ToMap() (map[string]interface{}, error) { + templateBDDHCPPolicyOpsMap := make(map[string]interface{}, 0) + A(templateBDDHCPPolicyOpsMap, "op", templateBDDHCPPolicyOps.Ops) + A(templateBDDHCPPolicyOpsMap, "path", templateBDDHCPPolicyOps.Path) + if templateBDDHCPPolicyOps.Value != nil { + A(templateBDDHCPPolicyOpsMap, "value", templateBDDHCPPolicyOps.Value) + } + return templateBDDHCPPolicyOpsMap, nil +} diff --git a/models/schema_template_contract_filter.go b/models/schema_template_contract_filter.go index ca629a7..869f28b 100644 --- a/models/schema_template_contract_filter.go +++ b/models/schema_template_contract_filter.go @@ -1,8 +1,8 @@ package models type TemplateContractFilter struct { - Ops string `json:",omitempty"` - Path string `json:",omitempty"` + Ops string `json:",omitempty"` + Path string `json:",omitempty"` Value string `json:",omitempty"` } @@ -13,7 +13,7 @@ type TemplateContractFilterRelationShip struct { } func NewTemplateContractFilter(ops, path, filterType string) *TemplateContractFilter { - + return &TemplateContractFilter{ Ops: ops, Path: path, @@ -26,9 +26,8 @@ func NewTemplateContractFilterRelationShip(ops, path string, filterRef map[strin var contractMap map[string]interface{} if ops != "remove" { contractMap = map[string]interface{}{ - "filterRef": filterRef, - "directives": directives, - + "filterRef": filterRef, + "directives": directives, } } else { contractMap = nil @@ -62,4 +61,3 @@ func (FilterAttributes *TemplateContractFilterRelationShip) ToMap() (map[string] return FilterAttributesMap, nil } - diff --git a/models/schema_template_externalepg_contract.go b/models/schema_template_externalepg_contract.go index 11a5c5d..0fc8f75 100644 --- a/models/schema_template_externalepg_contract.go +++ b/models/schema_template_externalepg_contract.go @@ -8,15 +8,14 @@ type ExternalEpgContract struct { func NewTemplateExternalEpgContract(ops, path, relationshipType string, contractRefMap map[string]interface{}) *ExternalEpgContract { var contractMap map[string]interface{} - if(ops != "remove"){ - contractMap = map[string]interface{}{ - "relationshipType": relationshipType, - "contractRef": contractRefMap, + if ops != "remove" { + contractMap = map[string]interface{}{ + "relationshipType": relationshipType, + "contractRef": contractRefMap, + } + } else { + contractMap = nil } - } else{ - contractMap = nil; - } - return &ExternalEpgContract{ Ops: ops, diff --git a/models/schema_template_filter_entry.go b/models/schema_template_filter_entry.go index 0d0f55d..33808ab 100644 --- a/models/schema_template_filter_entry.go +++ b/models/schema_template_filter_entry.go @@ -6,7 +6,7 @@ type TemplateFilterEntry struct { Value map[string]interface{} `json:",omitempty"` } -func NewTemplateFilterEntry(ops, path, entryName, entryDisplayName, entryDescription, etherType, arpFlag, ipProtocol, sourceFrom, sourceTo, destinationFrom, destinationTo string , matchOnlyFragments, stateful bool, tcpSessionRules []interface{}) *TemplateFilterEntry { +func NewTemplateFilterEntry(ops, path, entryName, entryDisplayName, entryDescription, etherType, arpFlag, ipProtocol, sourceFrom, sourceTo, destinationFrom, destinationTo string, matchOnlyFragments, stateful bool, tcpSessionRules []interface{}) *TemplateFilterEntry { var anpepgMap map[string]interface{} anpepgMap = map[string]interface{}{ @@ -26,30 +26,29 @@ func NewTemplateFilterEntry(ops, path, entryName, entryDisplayName, entryDescrip "tcpSessionRules": tcpSessionRules, } - if anpepgMap["etherType"]==""{ - anpepgMap["etherType"]="unspecified" + if anpepgMap["etherType"] == "" { + anpepgMap["etherType"] = "unspecified" } - if anpepgMap["arpFlag"]==""{ - anpepgMap["arpFlag"]="unspecified" + if anpepgMap["arpFlag"] == "" { + anpepgMap["arpFlag"] = "unspecified" } - if anpepgMap["ipProtocol"]==""{ - anpepgMap["ipProtocol"]="unspecified" + if anpepgMap["ipProtocol"] == "" { + anpepgMap["ipProtocol"] = "unspecified" } - - if anpepgMap["sourceFrom"]==""{ - anpepgMap["sourceFrom"]="unspecified" + + if anpepgMap["sourceFrom"] == "" { + anpepgMap["sourceFrom"] = "unspecified" } - if anpepgMap["sourceTo"]==""{ - anpepgMap["sourceTo"]="unspecified" + if anpepgMap["sourceTo"] == "" { + anpepgMap["sourceTo"] = "unspecified" } - if anpepgMap["destinationTo"]==""{ - anpepgMap["destinationTo"]="unspecified" + if anpepgMap["destinationTo"] == "" { + anpepgMap["destinationTo"] = "unspecified" } - if anpepgMap["destinationFrom"]==""{ - anpepgMap["destinationFrom"]="unspecified" + if anpepgMap["destinationFrom"] == "" { + anpepgMap["destinationFrom"] = "unspecified" } - return &TemplateFilterEntry{ Ops: ops, Path: path, @@ -84,7 +83,3 @@ func (anpAttributes *TemplateFilterEntry) ToMap() (map[string]interface{}, error return anpAttributesMap, nil } - - - - diff --git a/models/shema_validate.go b/models/shema_validate.go new file mode 100644 index 0000000..406febe --- /dev/null +++ b/models/shema_validate.go @@ -0,0 +1,6 @@ +package models + +type SchemValidate struct { + SchmaId string + Result string +} diff --git a/models/user.go b/models/user.go index fbb0eaf..4e015ea 100644 --- a/models/user.go +++ b/models/user.go @@ -1,42 +1,38 @@ package models type User struct { - Id string `json:",omitempty"` + Id string `json:",omitempty"` User string `json:",omitempty"` UserPassword string `json:",omitempty"` FirstName string `json:",omitempty"` - LastName string `json:",omitempty"` - Email string `json:",omitempty"` - Phone string `json:",omitempty"` - AccountStatus string `json:",omitempty"` - Domain string `json:",omitempty"` - Roles []interface{} `json:",omitempty"` - + LastName string `json:",omitempty"` + Email string `json:",omitempty"` + Phone string `json:",omitempty"` + AccountStatus string `json:",omitempty"` + Domain string `json:",omitempty"` + Roles []interface{} `json:",omitempty"` } // type Roles struct { // RoleId: - -// } +// } +func NewUser(id, user, userPassword, firstName, lastName, email, phone, accountStatus, domain string, roles []interface{}) *User { -func NewUser (id, user, userPassword, firstName,lastName,email,phone,accountStatus,domain string,roles []interface{}) *User { - return &User{ - Id: id, - User: user, + Id: id, + User: user, UserPassword: userPassword, - FirstName: firstName, - LastName: lastName, - Email: email, - Phone:phone, + FirstName: firstName, + LastName: lastName, + Email: email, + Phone: phone, AccountStatus: accountStatus, - Domain: domain, - Roles:roles, - + Domain: domain, + Roles: roles, } } @@ -53,6 +49,5 @@ func (user *User) ToMap() (map[string]interface{}, error) { A(userAttributeMap, "domainId", user.Domain) A(userAttributeMap, "roles", user.Roles) - return userAttributeMap, nil -} \ No newline at end of file +} diff --git a/models/util.go b/models/util.go index d63c86f..40431b8 100644 --- a/models/util.go +++ b/models/util.go @@ -63,8 +63,11 @@ func A(data map[string]interface{}, key string, value interface{}) { } } -func G(cont *container.Container, key string) string { - return StripQuotes(cont.S(key).String()) +func G(cont *container.Container, key ...string) string { + if cont.Exists(key...) { + return StripQuotes(cont.S(key...).String()) + } + return "" } func ListFromContainer(cont *container.Container, klass string) []*container.Container { @@ -85,3 +88,12 @@ func CurlyBraces(value string) string { return value } } + +func StringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +}