Skip to content

Commit

Permalink
Tool for detecting diff in NSX policy spec
Browse files Browse the repository at this point in the history
Tool that prints out new/deleted attributes in a predefined set
of model objects from baseline NSX spec to another NSX version
spec.
In addition, adjust policy generation tool to recent SDK changes and
make some further improvements.

Signed-off-by: Anna Khmelnitsky <[email protected]>
  • Loading branch information
annakhm committed Apr 20, 2023
1 parent 3f93a24 commit d484da0
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 51 deletions.
122 changes: 122 additions & 0 deletions tools/diffy/diffy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/python
# -*- coding: latin-1 -*-

# Copyright (c) 2023 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: MPL-2.0

# This script detects difference in model between different versions of NSX spec. List of relevant objects is for now hard-coded.

import sys
import re
import os
import json

OBJECTS = [
"ContextProfile",
"DhcpRelayConfig",
"DhcpServerConfig",
"Domain",
"EvpnConfig",
"EvpnTenantConfig",
"GatewayPolicy",
"Group",
"IPSecVpnDpdProfile",
"IPSecVpnIkeProfile",
"IPSecVpnService",
"IPSecVpnTunnelProfile",
"IPSecVpnLocalEndpoint",
"IdsPolicy",
"IdsProfile",
"IpAddressBlock",
"IpAddressPool",
"L2VPNService",
"L2VPNSession",
"LBPool",
"LBService",
"LBVirtualServer",
"MacDiscoveryProfile",
"OspfConfig",
"PolicyDnsForwarder",
"PolicyNatRule",
"PrefixList",
"QoSProfile",
"SecurityPolicy",
"Segment",
"Service",
"StaticRoutes",
"Tier0",
"Tier0Interface",
"Tier1",
"Tier1Interface"]

def load_spec(path):

with open(path, 'r') as f:
spec = json.load(f)

obj_map = {}
defs = spec["definitions"]
for key in defs:
if "allOf" not in defs[key]:
if "properties" in defs[key]:
# no inheritance
obj_map[key] = defs[key]["properties"]
continue
if len(defs[key]["allOf"]) == 2:
# object inheritance
if "properties" not in defs[key]["allOf"][1]:
continue
obj_map[key] = defs[key]["allOf"][1]["properties"]

return obj_map

def ref_to_def(ref):
return ref[len("#definitions/ "):]

def print_ident(text, level):
ident = " "*level
print("%s%s" % (ident, text))

class color:
PURPLE = '\033[95m'
BLUE = '\033[94m'
END = '\033[0m'

def main():

if len(sys.argv) < 3:
print("Usage: %s <baseline.json> <target.json>" % sys.argv[0])
sys.exit()

baseline_file_path = sys.argv[1]
target_file_path = sys.argv[2]
baseline_map = load_spec(baseline_file_path)
target_map = load_spec(target_file_path)
level = 0

def analyze_obj(obj, level):
print_ident("analyzing %s.." % obj, level)
if obj not in baseline_map:
return
for attr in target_map[obj]:
if attr not in baseline_map[obj]:
print_ident(color.BLUE + "new attribute %s" % attr + color.END, level + 1)

if "$ref" in target_map[obj][attr]:
analyze_obj(ref_to_def(target_map[obj][attr]["$ref"]), level + 1)
if "items" in target_map[obj][attr] and "$ref" in target_map[obj][attr]["items"]:
analyze_obj(ref_to_def(target_map[obj][attr]["items"]["$ref"]), level + 1)

for attr in baseline_map[obj]:
if obj not in target_map:
continue
if attr not in target_map[obj]:
print_ident(color.PURPLE + "deleted attribute %s" % attr + color.END, level + 1)

for obj in OBJECTS:
analyze_obj(obj, level + 1)


print("Done.")

main()
4 changes: 2 additions & 2 deletions tools/resource_nsxt_policy_doc_template
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ In addition to arguments listed above, the following attributes are exported:

An existing object can be [imported][docs-import] into this resource, via the following command:

[docs-import]: /docs/import/index.html
[docs-import]: https://www.terraform.io/cli/import

```
terraform import nsxt_policy_<!resource_lower!>.test UUID
```

The above command imports <!RESOURCE!> named `test` with the NSX <!RESOURCE!> ID `UUID`.
The above command imports <!RESOURCE!> named `test` with the NSX ID `UUID`.
60 changes: 19 additions & 41 deletions tools/resource_nsxt_policy_template
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func resourceNsxtPolicy<!RESOURCE!>() *schema.Resource {
}
}

func resourceNsxtPolicy<!RESOURCE!>Exists(id string, connector *client.RestConnector, isGlobalManager bool) (bool, error) {
func resourceNsxtPolicy<!RESOURCE!>Exists(id string, connector client.Connector, isGlobalManager bool) (bool, error) {
var err error
if isGlobalManager {
client := gm_infra.New<!RESOURCE!>sClient(connector)
Expand All @@ -60,15 +60,9 @@ func resourceNsxtPolicy<!RESOURCE!>Exists(id string, connector *client.RestConne
return false, logAPIError("Error retrieving resource", err)
}

func resourceNsxtPolicy<!RESOURCE!>Create(d *schema.ResourceData, m interface{}) error {
func resourceNsxtPolicy<!RESOURCE!>Patch(d *schema.ResourceData, m interface{}, id string) error {
connector := getPolicyConnector(m)

// Initialize resource Id and verify this ID is not yet used
id, err := getOrGenerateID(d, m, resourceNsxtPolicy<!RESOURCE!>Exists)
if err != nil {
return err
}

displayName := d.Get("display_name").(string)
description := d.Get("description").(string)
tags := getPolicyTagsFromSchema(d)
Expand All @@ -81,19 +75,29 @@ func resourceNsxtPolicy<!RESOURCE!>Create(d *schema.ResourceData, m interface{})
<!SET_ATTRS_IN_OBJ!>
}

// Create the resource using PATCH
log.Printf("[INFO] Creating <!RESOURCE!> with ID %s", id)
log.Printf("[INFO] Patching <!RESOURCE!> with ID %s", id)
if isPolicyGlobalManager(m) {
gmObj, convErr := convertModelBindingType(obj, model.<!RESOURCE!>BindingType(), gm_model.<!RESOURCE!>BindingType())
if convErr != nil {
return convErr
}
client := gm_infra.New<!RESOURCE!>sClient(connector)
err = client.Patch(id, gmObj.(gm_model.<!RESOURCE!>))
} else {
client := infra.New<!RESOURCE!>sClient(connector)
err = client.Patch(id, obj)
return client.Patch(id, gmObj.(gm_model.<!RESOURCE!>))
}

client := infra.New<!RESOURCE!>sClient(connector)
return client.Patch(id, obj)
}

func resourceNsxtPolicy<!RESOURCE!>Create(d *schema.ResourceData, m interface{}) error {

// Initialize resource Id and verify this ID is not yet used
id, err := getOrGenerateID(d, m, resourceNsxtPolicy<!RESOURCE!>Exists)
if err != nil {
return err
}

err = resourceNsxtPolicy<!RESOURCE!>Patch(d, m, id)
if err != nil {
return handleCreateError("<!RESOURCE!>", id, err)
}
Expand Down Expand Up @@ -147,39 +151,13 @@ func resourceNsxtPolicy<!RESOURCE!>Read(d *schema.ResourceData, m interface{}) e
}

func resourceNsxtPolicy<!RESOURCE!>Update(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)

id := d.Id()
if id == "" {
return fmt.Errorf("Error obtaining <!RESOURCE!> ID")
}

// Read the rest of the configured parameters
description := d.Get("description").(string)
displayName := d.Get("display_name").(string)
tags := getPolicyTagsFromSchema(d)

<!GET_ATTRS_FROM_SCHEMA!>

obj := model.<!RESOURCE!>{
DisplayName: &displayName,
Description: &description,
Tags: tags,
<!SET_ATTRS_IN_OBJ!>
}

var err error
if isPolicyGlobalManager(m) {
gmObj, convErr := convertModelBindingType(obj, model.<!RESOURCE!>BindingType(), gm_model.<!RESOURCE!>BindingType())
if convErr != nil {
return convErr
}
client := gm_infra.New<!RESOURCE!>sClient(connector)
_, err = client.Update(id, gmObj.(gm_model.<!RESOURCE!>))
} else {
client := infra.New<!RESOURCE!>sClient(connector)
_, err = client.Update(id, obj)
}
err := resourceNsxtPolicy<!RESOURCE!>Patch(d, m, id)
if err != nil {
return handleUpdateError("<!RESOURCE!>", id, err)
}
Expand Down
8 changes: 0 additions & 8 deletions tools/resource_nsxt_policy_test_template
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ resource "nsxt_policy_<!resource_lower!>" "test" {
scope = "scope1"
tag = "tag1"
}
}

data "nsxt_policy_realization_info" "realization_info" {
path = nsxt_policy_<!resource_lower!>.test.path
}`, attrMap["display_name"], attrMap["description"]<!TEST_ATTRS_SPRINTF!>)
}

Expand All @@ -174,9 +170,5 @@ func testAccNsxtPolicy<!RESOURCE!>Minimalistic() string {
resource "nsxt_policy_<!resource_lower!>" "test" {
display_name = "%s"
<!TEST_REQUIRED_ATTRS!>
}

data "nsxt_policy_realization_info" "realization_info" {
path = nsxt_policy_<!resource_lower!>.test.path
}`, accTestPolicy<!RESOURCE!>UpdateAttributes["display_name"]<!TEST_REQUIRED_ATTRS_SPRINTF!>)
}

0 comments on commit d484da0

Please sign in to comment.