ygot icon indicating copy to clipboard operation
ygot copied to clipboard

Presence container support

Open rajeshs1 opened this issue 5 years ago • 4 comments

ygot version 0.6.0

My yang file has a presence container (interfaces-ip-dhcp:dhcp-client). https://tools.ietf.org/html/rfc6020#page-52

While using the EmitJSON() method, the JSON output does not have the empty container. Ideally the input cfgjson data after marshal and emitjson should result in the same.

in ygot/render.go, the structJson method skips if the container is empty.

                if util.IsYgotAnnotation(fType) {
			value, err = jsonAnnotationSlice(field)
		} else {
			value, err = jsonValue(field, pmod, args)
		}
		if err != nil {
			errs.Add(err)
			continue
		}
		if value == nil {
			continue
		}

After the jsondata is Unmarshalled, the value of the dhcp-client is nil. And the structJson method skips this dhcp-client container during EmitJSON Is there any plan to support the presence container. Here are some details:

cfg

{
  "interface": [
    {
      "name": "inst0",
      "admin-state": "enable",
      "subinterface": [
        {
          "index": 0,
          "admin-state": "enable",
          "ipv4": {
            "interfaces-ip-dhcp:dhcp-client": {  
            }
          }
        }
      ]
    }
  ]
}	

Here’s a snippet of my code:

device := &oc.Device{}
	err := oc.Unmarshal(cfg, device, &ytypes.IgnoreExtraFields{})

	cfgdata, err = ygot.EmitJSON(device, &ygot.EmitJSONConfig{
		Format:         ygot.RFC7951,
		Indent:         "",
		RFC7951Config: &ygot.RFC7951JSONConfig{
			AppendModuleName: false,
		},
	})

Actual cfgData

{
   "interface":[
      {
         "admin-state":"enable",
         "name":"inst0",
         "subinterface":[
            {
               "admin-state":"enable",
               "index":0
            }
         ]
      }
   ]
}

Expected cfgData

{
   "interface":[
      {
         "admin-state":"enable",
         "name":"inst0",
         "subinterface":[
            {
               "admin-state":"enable",
               "index":0,
                "ipv4": {
                  "interfaces-ip-dhcp:dhcp-client": {  //Presence container
                }
              }
            }
         ]
      }
   ]
}

rajeshs1 avatar Nov 14 '19 20:11 rajeshs1

Hi @robshakir , is there any plan for this enhancement?

rajeshs1 avatar Dec 19 '19 01:12 rajeshs1

hi,

There isn't currently a plan to add presence support to ygot. I'd be happy to review a patch for this though. I suggest that the easiest way to do this is to add an annotation to presence containers within the struct tag, and then make the struct rendering method check for whether that tag is there before deleting the empty container.

Cheers, r.

robshakir avatar Mar 10 '20 23:03 robshakir

Hi Rob,

I plan to add this support. Can you please provide some pointers in the ygot code which I can take a look?

Thanks Soumik

soumiksamanta avatar May 27 '21 22:05 soumiksamanta

Hi Soumik, this is where the JSON marshalling routine skips over empty containers. https://github.com/openconfig/ygot/blob/2713b986ad5a22464ae5e72e919be9f519466246/ygot/render.go#L1078-L1080

Like Rob said, I think it makes sense to add a struct tag when generating code to make this do something different for presence containers.

The most involved part is probably modifying ygen to generate the tags. One way to do this is to access this field during the population of the struct tags here: https://github.com/openconfig/ygot/blob/2713b986ad5a22464ae5e72e919be9f519466246/ygen/gogen.go#L1563-L1587 You can get the presence field from targetStruct.Entry.Node after casting it to the Container type.

wenovus avatar Jun 17 '21 18:06 wenovus