objects.go raw

   1  package ibclient
   2  
   3  import (
   4  	"bytes"
   5  	"encoding/json"
   6  	"fmt"
   7  	"reflect"
   8  	"time"
   9  )
  10  
  11  const MACADDR_ZERO = "00:00:00:00:00:00"
  12  
  13  type Bool bool
  14  
  15  func (b Bool) MarshalJSON() ([]byte, error) {
  16  	if b {
  17  		return json.Marshal("True")
  18  	}
  19  
  20  	return json.Marshal("False")
  21  }
  22  
  23  type EA map[string]interface{}
  24  
  25  func (ea EA) Count() int {
  26  	return len(ea)
  27  }
  28  
  29  func (ea EA) MarshalJSON() ([]byte, error) {
  30  	m := make(map[string]interface{})
  31  	for k, v := range ea {
  32  		value := make(map[string]interface{})
  33  		value["value"] = v
  34  		m[k] = value
  35  	}
  36  
  37  	return json.Marshal(m)
  38  }
  39  
  40  func (ea *EA) UnmarshalJSON(b []byte) (err error) {
  41  	var m map[string]map[string]interface{}
  42  
  43  	decoder := json.NewDecoder(bytes.NewBuffer(b))
  44  	decoder.UseNumber()
  45  	err = decoder.Decode(&m)
  46  	if err != nil {
  47  		return
  48  	}
  49  
  50  	*ea = make(EA)
  51  	for k, v := range m {
  52  		val := v["value"]
  53  		switch valType := reflect.TypeOf(val).String(); valType {
  54  		case "json.Number":
  55  			var i64 int64
  56  			i64, err = val.(json.Number).Int64()
  57  			val = int(i64)
  58  		case "string":
  59  			if val.(string) == "True" {
  60  				val = Bool(true)
  61  			} else if val.(string) == "False" {
  62  				val = Bool(false)
  63  			}
  64  		case "[]interface {}":
  65  			nval := val.([]interface{})
  66  			nVals := make([]string, len(nval))
  67  			for i, v := range nval {
  68  				nVals[i] = fmt.Sprintf("%v", v)
  69  			}
  70  			val = nVals
  71  		default:
  72  			val = fmt.Sprintf("%v", val)
  73  		}
  74  
  75  		(*ea)[k] = val
  76  	}
  77  
  78  	return
  79  }
  80  
  81  type EASearch map[string]interface{}
  82  
  83  func (eas EASearch) MarshalJSON() ([]byte, error) {
  84  	m := make(map[string]interface{})
  85  	for k, v := range eas {
  86  		m["*"+k] = v
  87  	}
  88  
  89  	return json.Marshal(m)
  90  }
  91  
  92  type IBBase struct {
  93  	returnFields []string
  94  	eaSearch     EASearch
  95  }
  96  
  97  type IBObject interface {
  98  	ObjectType() string
  99  	ReturnFields() []string
 100  	EaSearch() EASearch
 101  	SetReturnFields([]string)
 102  }
 103  
 104  func (obj *IBBase) ReturnFields() []string {
 105  	return obj.returnFields
 106  }
 107  
 108  func (obj *IBBase) SetReturnFields(rf []string) {
 109  	obj.returnFields = rf
 110  }
 111  
 112  func (obj *IBBase) EaSearch() EASearch {
 113  	return obj.eaSearch
 114  }
 115  
 116  // QueryParams is a general struct to add query params used in makeRequest
 117  type QueryParams struct {
 118  	forceProxy bool
 119  
 120  	searchFields map[string]string
 121  }
 122  
 123  func NewQueryParams(forceProxy bool, searchFields map[string]string) *QueryParams {
 124  	qp := QueryParams{forceProxy: forceProxy}
 125  	if searchFields != nil {
 126  		qp.searchFields = searchFields
 127  	} else {
 128  		qp.searchFields = make(map[string]string)
 129  	}
 130  
 131  	return &qp
 132  }
 133  
 134  type RequestBody struct {
 135  	Data               map[string]interface{} `json:"data,omitempty"`
 136  	Args               map[string]string      `json:"args,omitempty"`
 137  	Method             string                 `json:"method"`
 138  	Object             string                 `json:"object,omitempty"`
 139  	EnableSubstitution bool                   `json:"enable_substitution,omitempty"`
 140  	AssignState        map[string]string      `json:"assign_state,omitempty"`
 141  	Discard            bool                   `json:"discard,omitempty"`
 142  }
 143  
 144  type SingleRequest struct {
 145  	IBBase `json:"-"`
 146  	Body   *RequestBody
 147  }
 148  
 149  type MultiRequest struct {
 150  	IBBase `json:"-"`
 151  	Body   []*RequestBody
 152  }
 153  
 154  func (r *MultiRequest) MarshalJSON() ([]byte, error) {
 155  	return json.Marshal(r.Body)
 156  }
 157  
 158  func NewMultiRequest(body []*RequestBody) *MultiRequest {
 159  	req := &MultiRequest{Body: body}
 160  	return req
 161  }
 162  
 163  func (MultiRequest) ObjectType() string {
 164  	return "request"
 165  }
 166  
 167  func NewRequest(body *RequestBody) *SingleRequest {
 168  	req := &SingleRequest{Body: body}
 169  	return req
 170  }
 171  
 172  func (SingleRequest) ObjectType() string {
 173  	return "request"
 174  }
 175  
 176  type NextavailableIPv4Addrs struct {
 177  	NextavailableIPv4Addr IpNextAvailableInfo `json:"ipv4addr,omitempty"`
 178  }
 179  
 180  type NextavailableIPv6Addrs struct {
 181  	NextavailableIPv6Addr IpNextAvailableInfo `json:"ipv6addr,omitempty"`
 182  }
 183  
 184  type IpNextAvailable struct {
 185  	IBBase                 `json:"-"`
 186  	objectType             string
 187  	Name                   string                   `json:"name"`
 188  	NextAvailableIPv4Addr  *IpNextAvailableInfo     `json:"ipv4addr,omitempty"`
 189  	NextAvailableIPv6Addr  *IpNextAvailableInfo     `json:"ipv6addr,omitempty"`
 190  	NextAvailableIPv4Addrs []NextavailableIPv4Addrs `json:"ipv4addrs,omitempty"`
 191  	NextAvailableIPv6Addrs []NextavailableIPv6Addrs `json:"ipv6addrs,omitempty"`
 192  	Comment                string                   `json:"comment"`
 193  	Ea                     EA                       `json:"extattrs"`
 194  	Disable                bool                     `json:"disable,omitempty"`
 195  	EnableDns              *bool                    `json:"configure_for_dns,omitempty"`
 196  	EnableDhcp             bool                     `json:"configure_for_dhcp,omitempty"`
 197  	MacAddr                string                   `json:"mac,omitempty"`
 198  	Duid                   string                   `json:"duid,omitempty"`
 199  	NetworkView            string                   `json:"network_view,omitempty"`
 200  	DnsView                string                   `json:"view,omitempty"`
 201  	UseTtl                 bool                     `json:"use_ttl,omitempty"`
 202  	Ttl                    uint32                   `json:"ttl,omitempty"`
 203  	Aliases                []string                 `json:"aliases,omitempty"`
 204  }
 205  
 206  func (ni *IpNextAvailable) ObjectType() string {
 207  	return ni.objectType
 208  }
 209  
 210  func (ni *IpNextAvailable) SetObjectType(objectType string) {
 211  	ni.objectType = objectType
 212  }
 213  
 214  type IpNextAvailableInfo struct {
 215  	Function         string              `json:"_object_function"`
 216  	ResultField      string              `json:"_result_field"`
 217  	Object           string              `json:"_object"`
 218  	ObjectParams     map[string]string   `json:"_object_parameters"`
 219  	Params           map[string][]string `json:"_parameters"`
 220  	NetviewName      string              `json:"network_view,omitempty"`
 221  	UseEaInheritance bool                `json:"use_for_ea_inheritance"`
 222  	EnableDhcp       bool                `json:"configure_for_dhcp,omitempty"`
 223  	MacAddr          string              `json:"mac,omitempty"`
 224  	Duid             string              `json:"duid,omitempty"`
 225  }
 226  
 227  func NewIpNextAvailableInfo(objectParams map[string]string, params map[string][]string, useEaInheritance bool, ipAddrType string) *IpNextAvailableInfo {
 228  	nextAvailableIpInfo := IpNextAvailableInfo{
 229  		Function:         "next_available_ip",
 230  		ResultField:      "ips",
 231  		ObjectParams:     objectParams,
 232  		Params:           params,
 233  		UseEaInheritance: useEaInheritance,
 234  	}
 235  
 236  	if ipAddrType == "IPV6" {
 237  		nextAvailableIpInfo.Object = "ipv6network"
 238  	} else {
 239  		nextAvailableIpInfo.Object = "network"
 240  	}
 241  
 242  	return &nextAvailableIpInfo
 243  }
 244  
 245  func NewIpNextAvailable(name string, objectType string, objectParams map[string]string, params map[string][]string,
 246  	useEaInheritance bool, ea EA, comment string, disable bool, n *int, ipAddrType string,
 247  	enableDns bool, enableDhcp bool, macAddr string, duid string, networkView string, dnsView string, useTtl bool, ttl uint32, aliases []string) *IpNextAvailable {
 248  
 249  	nextAvailableIP := IpNextAvailable{
 250  		Name:       name,
 251  		objectType: objectType,
 252  		Ea:         ea,
 253  		Comment:    comment,
 254  		Disable:    disable,
 255  		UseTtl:     useTtl,
 256  		Ttl:        ttl,
 257  		DnsView:    dnsView,
 258  	}
 259  
 260  	enableDhcpv6 := enableDhcp && duid != ""
 261  	enableDhcpv4 := enableDhcp && macAddr != "" && macAddr != MACADDR_ZERO
 262  
 263  	if n != nil && *n > 1 {
 264  		ipInfo := make([]IpNextAvailableInfo, *n)
 265  		for i := 0; i < *n; i++ {
 266  			ipInfo[i] = *NewIpNextAvailableInfo(objectParams, params, useEaInheritance, ipAddrType)
 267  			if ipAddrType == "IPV6" {
 268  				ipInfo[i].EnableDhcp = enableDhcpv6
 269  				ipInfo[i].Duid = duid
 270  
 271  				nextAvailableIP.NextAvailableIPv6Addrs = append(nextAvailableIP.NextAvailableIPv6Addrs, NextavailableIPv6Addrs{NextavailableIPv6Addr: ipInfo[i]})
 272  			} else {
 273  				ipInfo[i].EnableDhcp = enableDhcpv4
 274  				ipInfo[i].MacAddr = macAddr
 275  				nextAvailableIP.NextAvailableIPv4Addrs = append(nextAvailableIP.NextAvailableIPv4Addrs, NextavailableIPv4Addrs{NextavailableIPv4Addr: ipInfo[i]})
 276  			}
 277  		}
 278  	} else {
 279  		ipInfo := NewIpNextAvailableInfo(objectParams, params, useEaInheritance, ipAddrType)
 280  		switch objectType {
 281  		case "record:a":
 282  			nextAvailableIP.NextAvailableIPv4Addr = ipInfo
 283  		case "record:aaaa":
 284  			nextAvailableIP.NextAvailableIPv6Addr = ipInfo
 285  		case "record:host":
 286  			{
 287  				nextAvailableIP.EnableDns = &enableDns
 288  				nextAvailableIP.NetworkView = networkView
 289  				nextAvailableIP.Aliases = aliases
 290  
 291  				switch ipAddrType {
 292  				case "IPV4":
 293  					ipInfo.EnableDhcp = enableDhcpv4
 294  					ipInfo.MacAddr = macAddr
 295  					nextAvailableIP.NextAvailableIPv4Addrs = []NextavailableIPv4Addrs{{*ipInfo}}
 296  				case "IPV6":
 297  					ipInfo.EnableDhcp = enableDhcpv6
 298  					ipInfo.Duid = duid
 299  					nextAvailableIP.NextAvailableIPv6Addrs = []NextavailableIPv6Addrs{{*ipInfo}}
 300  				case "Both":
 301  					ipv4Info := NewIpNextAvailableInfo(objectParams, params, useEaInheritance, "IPV4")
 302  					ipv4Info.EnableDhcp = enableDhcpv4
 303  					ipv4Info.MacAddr = macAddr
 304  					nextAvailableIP.NextAvailableIPv4Addrs = []NextavailableIPv4Addrs{{*ipv4Info}}
 305  
 306  					ipv6Info := NewIpNextAvailableInfo(objectParams, params, useEaInheritance, "IPV6")
 307  					ipv6Info.EnableDhcp = enableDhcpv6
 308  					ipv6Info.Duid = duid
 309  					nextAvailableIP.NextAvailableIPv6Addrs = []NextavailableIPv6Addrs{{*ipv6Info}}
 310  				}
 311  			}
 312  		}
 313  
 314  	}
 315  	return &nextAvailableIP
 316  }
 317  
 318  type NetworkContainerNextAvailable struct {
 319  	IBBase      `json:"-"`
 320  	objectType  string
 321  	Network     *NetworkContainerNextAvailableInfo `json:"network"`
 322  	NetviewName string                             `json:"network_view,omitempty"`
 323  	Comment     string                             `json:"comment"`
 324  	Ea          EA                                 `json:"extattrs"`
 325  }
 326  
 327  func (nc *NetworkContainerNextAvailable) ObjectType() string {
 328  	return nc.objectType
 329  }
 330  
 331  func (nc *NetworkContainerNextAvailable) SetObjectType(objectType string) {
 332  	nc.objectType = objectType
 333  }
 334  
 335  type NetworkContainerNextAvailableInfo struct {
 336  	Function     string            `json:"_object_function"`
 337  	ResultField  string            `json:"_result_field"`
 338  	Object       string            `json:"_object"`
 339  	ObjectParams map[string]string `json:"_object_parameters"`
 340  	Params       map[string]uint   `json:"_parameters"`
 341  	NetviewName  string            `json:"network_view,omitempty"`
 342  }
 343  
 344  func NewNetworkContainerNextAvailableInfo(netview, cidr string, prefixLen uint, isIPv6 bool) *NetworkContainerNextAvailableInfo {
 345  	containerInfo := NetworkContainerNextAvailableInfo{
 346  		Function:     "next_available_network",
 347  		ResultField:  "networks",
 348  		ObjectParams: map[string]string{"network": cidr},
 349  		Params:       map[string]uint{"cidr": prefixLen},
 350  		NetviewName:  netview,
 351  	}
 352  
 353  	if isIPv6 {
 354  		containerInfo.Object = "ipv6networkcontainer"
 355  	} else {
 356  		containerInfo.Object = "networkcontainer"
 357  	}
 358  
 359  	return &containerInfo
 360  }
 361  
 362  func NewNetworkContainerNextAvailable(ncav *NetworkContainerNextAvailableInfo, isIPv6 bool, comment string, ea EA) *NetworkContainerNextAvailable {
 363  	nc := &NetworkContainerNextAvailable{
 364  		Network:     ncav,
 365  		NetviewName: ncav.NetviewName,
 366  		Ea:          ea,
 367  		Comment:     comment,
 368  	}
 369  
 370  	if isIPv6 {
 371  		nc.objectType = "ipv6networkcontainer"
 372  	} else {
 373  		nc.objectType = "networkcontainer"
 374  	}
 375  	nc.returnFields = []string{"extattrs", "network", "network_view", "comment"}
 376  
 377  	return nc
 378  }
 379  
 380  type FixedAddress struct {
 381  	IBBase                      `json:"-"`
 382  	objectType                  string
 383  	Ref                         string            `json:"_ref,omitempty"`
 384  	NetviewName                 string            `json:"network_view,omitempty"`
 385  	Cidr                        string            `json:"network,omitempty"`
 386  	Comment                     string            `json:"comment"`
 387  	IPv4Address                 string            `json:"ipv4addr,omitempty"`
 388  	IPv6Address                 string            `json:"ipv6addr,omitempty"`
 389  	Duid                        string            `json:"duid,omitempty"`
 390  	Mac                         *string           `json:"mac,omitempty"`
 391  	Name                        *string           `json:"name,omitempty"`
 392  	MatchClient                 *string           `json:"match_client,omitempty"`
 393  	AgentCircuitId              *string           `json:"agent_circuit_id,omitempty"`
 394  	AgentRemoteId               *string           `json:"agent_remote_id,omitempty"`
 395  	ClientIdentifierPrependZero *bool             `json:"client_identifier_prepend_zero,omitempty"`
 396  	Options                     []*Dhcpoption     `json:"options,omitempty"`
 397  	UseOptions                  *bool             `json:"use_options,omitempty"`
 398  	CloudInfo                   *GridCloudapiInfo `json:"cloud_info,omitempty"`
 399  	Disable                     *bool             `json:"disable,omitempty"`
 400  	DhcpClientIdentifier        *string           `json:"dhcp_client_identifier,omitempty"`
 401  	Ea                          EA                `json:"extattrs"`
 402  }
 403  
 404  func (fa FixedAddress) ObjectType() string {
 405  	return fa.objectType
 406  }
 407  
 408  func NewEmptyFixedAddress(isIPv6 bool) *FixedAddress {
 409  	res := &FixedAddress{}
 410  	res.Ea = make(EA)
 411  	if isIPv6 {
 412  		res.objectType = "ipv6fixedaddress"
 413  		res.returnFields = []string{"extattrs", "ipv6addr", "duid", "name", "network", "network_view", "comment"}
 414  	} else {
 415  		res.objectType = "fixedaddress"
 416  		res.returnFields = []string{"extattrs", "ipv4addr", "mac", "name", "network", "network_view", "comment", "match_client", "agent_circuit_id", "agent_remote_id", "client_identifier_prepend_zero", "options", "use_options", "cloud_info", "disable", "dhcp_client_identifier"}
 417  	}
 418  	return res
 419  }
 420  
 421  func NewFixedAddress(
 422  	netView string,
 423  	name string,
 424  	ipAddr string,
 425  	cidr string,
 426  	macOrDuid string,
 427  	clients *string,
 428  	eas EA,
 429  	ref string,
 430  	isIPv6 bool,
 431  	comment string,
 432  	agentCircuitId *string,
 433  	agentRemoteId *string,
 434  	clientIdentifierPrependZero *bool,
 435  	dhcpClientIdentifier *string,
 436  	disable bool,
 437  	Options []*Dhcpoption,
 438  	useOptions bool,
 439  ) *FixedAddress {
 440  
 441  	res := NewEmptyFixedAddress(isIPv6)
 442  	res.NetviewName = netView
 443  	res.Name = &name
 444  	res.Cidr = cidr
 445  	res.MatchClient = clients
 446  	res.Ea = eas
 447  	res.Ref = ref
 448  	res.Comment = comment
 449  	if isIPv6 {
 450  		res.IPv6Address = ipAddr
 451  		res.Duid = macOrDuid
 452  	} else {
 453  		res.IPv4Address = ipAddr
 454  		res.Mac = &macOrDuid
 455  	}
 456  	res.AgentCircuitId = agentCircuitId
 457  	res.AgentRemoteId = agentRemoteId
 458  	res.ClientIdentifierPrependZero = clientIdentifierPrependZero
 459  	res.DhcpClientIdentifier = dhcpClientIdentifier
 460  	res.Disable = &disable
 461  	res.Options = Options
 462  	res.UseOptions = &useOptions
 463  	return res
 464  }
 465  
 466  func NewEmptyDNSView() *View {
 467  	res := &View{}
 468  	res.returnFields = []string{"extattrs", "name", "network_view", "comment"}
 469  	return res
 470  }
 471  
 472  type Network struct {
 473  	IBBase      `json:"-"`
 474  	objectType  string
 475  	Ref         string          `json:"_ref,omitempty"`
 476  	NetviewName string          `json:"network_view,omitempty"`
 477  	Cidr        string          `json:"network,omitempty"`
 478  	Ea          EA              `json:"extattrs"`
 479  	Comment     string          `json:"comment"`
 480  	Members     []NetworkMember `json:"members,omitempty"`
 481  }
 482  type NetworkMember struct {
 483  	DhcpMember   *Dhcpmember   `json:"dhcpmember,omitempty"`
 484  	MsDhcpServer *Msdhcpserver `json:"msdhcpserver,omitempty"`
 485  }
 486  
 487  // Custom JSON Marshaling
 488  func (nm NetworkMember) MarshalJSON() ([]byte, error) {
 489  	if nm.DhcpMember != nil {
 490  		return json.Marshal(struct {
 491  			Struct   string `json:"_struct"`
 492  			Name     string `json:"name,omitempty"`
 493  			Ipv4Addr string `json:"ipv4addr,omitempty"`
 494  			Ipv6Addr string `json:"ipv6addr,omitempty"`
 495  		}{
 496  			Struct:   "dhcpmember",
 497  			Name:     nm.DhcpMember.Name,
 498  			Ipv4Addr: nm.DhcpMember.Ipv4Addr,
 499  			Ipv6Addr: nm.DhcpMember.Ipv6Addr,
 500  		})
 501  	} else if nm.MsDhcpServer != nil {
 502  		return json.Marshal(struct {
 503  			Struct   string `json:"_struct"`
 504  			Ipv4Addr string `json:"ipv4addr,omitempty"`
 505  		}{
 506  			Struct:   "msdhcpserver",
 507  			Ipv4Addr: nm.MsDhcpServer.Ipv4Addr,
 508  		})
 509  	}
 510  	return json.Marshal(struct{}{})
 511  }
 512  func (nm *NetworkMember) UnmarshalJSON(data []byte) error {
 513  	var raw map[string]json.RawMessage
 514  	if err := json.Unmarshal(data, &raw); err != nil {
 515  		return err
 516  	}
 517  
 518  	var structType string
 519  	if err := json.Unmarshal(raw["_struct"], &structType); err != nil {
 520  		return err
 521  	}
 522  
 523  	switch structType {
 524  	case "dhcpmember":
 525  		var dhcpMember struct {
 526  			Name     string `json:"name,omitempty"`
 527  			Ipv4Addr string `json:"ipv4addr,omitempty"`
 528  			Ipv6Addr string `json:"ipv6addr,omitempty"`
 529  		}
 530  		if err := json.Unmarshal(data, &dhcpMember); err != nil {
 531  			return err
 532  		}
 533  		nm.DhcpMember = &Dhcpmember{
 534  			Name:     dhcpMember.Name,
 535  			Ipv4Addr: dhcpMember.Ipv4Addr,
 536  			Ipv6Addr: dhcpMember.Ipv6Addr,
 537  		}
 538  		nm.MsDhcpServer = nil
 539  	case "msdhcpserver":
 540  		var msDhcpServer struct {
 541  			Ipv4Addr string `json:"ipv4addr,omitempty"`
 542  		}
 543  		if err := json.Unmarshal(data, &msDhcpServer); err != nil {
 544  			return err
 545  		}
 546  		nm.MsDhcpServer = &Msdhcpserver{
 547  			Ipv4Addr: msDhcpServer.Ipv4Addr,
 548  		}
 549  		nm.DhcpMember = nil
 550  	default:
 551  		return fmt.Errorf("unknown struct type: %s", structType)
 552  	}
 553  
 554  	return nil
 555  }
 556  func (n Network) ObjectType() string {
 557  	return n.objectType
 558  }
 559  
 560  func NewNetwork(netview string, cidr string, isIPv6 bool, comment string, ea EA) *Network {
 561  	var res Network
 562  	res.NetviewName = netview
 563  	res.Cidr = cidr
 564  	res.Ea = ea
 565  	res.Comment = comment
 566  	if isIPv6 {
 567  		res.objectType = "ipv6network"
 568  	} else {
 569  		res.objectType = "network"
 570  	}
 571  	res.returnFields = []string{"extattrs", "network", "network_view", "comment"}
 572  
 573  	return &res
 574  }
 575  
 576  type NetworkContainer struct {
 577  	IBBase      `json:"-"`
 578  	objectType  string
 579  	Ref         string `json:"_ref,omitempty"`
 580  	NetviewName string `json:"network_view,omitempty"`
 581  	Cidr        string `json:"network,omitempty"`
 582  	Comment     string `json:"comment"`
 583  	Ea          EA     `json:"extattrs"`
 584  }
 585  
 586  func (nc NetworkContainer) ObjectType() string {
 587  	return nc.objectType
 588  }
 589  
 590  func NewNetworkContainer(netview, cidr string, isIPv6 bool, comment string, ea EA) *NetworkContainer {
 591  	nc := NetworkContainer{
 592  		NetviewName: netview,
 593  		Cidr:        cidr,
 594  		Ea:          ea,
 595  		Comment:     comment,
 596  	}
 597  
 598  	if isIPv6 {
 599  		nc.objectType = "ipv6networkcontainer"
 600  	} else {
 601  		nc.objectType = "networkcontainer"
 602  	}
 603  	nc.returnFields = []string{"extattrs", "network", "network_view", "comment"}
 604  
 605  	return &nc
 606  }
 607  
 608  // License represents license wapi object
 609  type License struct {
 610  	IBBase           `json:"-"`
 611  	objectType       string
 612  	Ref              string `json:"_ref,omitempty"`
 613  	ExpirationStatus string `json:"expiration_status,omitempty"`
 614  	ExpiryDate       int    `json:"expiry_date,omitempty"`
 615  	HwID             string `json:"hwid,omitempty"`
 616  	Key              string `json:"key,omitempty"`
 617  	Kind             string `json:"kind,omitempty"`
 618  	Limit            string `json:"limit,omitempty"`
 619  	LimitContext     string `json:"limit_context,omitempty"`
 620  	Licensetype      string `json:"type,omitempty"`
 621  }
 622  
 623  func (l License) ObjectType() string {
 624  	return l.objectType
 625  }
 626  
 627  func NewGridLicense(license License) *License {
 628  	result := license
 629  	result.objectType = "license:gridwide"
 630  	returnFields := []string{"expiration_status",
 631  		"expiry_date",
 632  		"key",
 633  		"limit",
 634  		"limit_context",
 635  		"type"}
 636  	result.returnFields = returnFields
 637  	return &result
 638  }
 639  
 640  func NewLicense(license License) *License {
 641  	result := license
 642  	returnFields := []string{"expiration_status",
 643  		"expiry_date",
 644  		"hwid",
 645  		"key",
 646  		"kind",
 647  		"limit",
 648  		"limit_context",
 649  		"type"}
 650  	result.objectType = "member:license"
 651  	result.returnFields = returnFields
 652  	return &result
 653  }
 654  
 655  var mxRecordReturnFieldsList = []string{"mail_exchanger", "view", "name", "preference", "ttl", "use_ttl", "comment", "extattrs", "zone"}
 656  
 657  func NewEmptyRecordMX() *RecordMX {
 658  	res := &RecordMX{}
 659  	res.returnFields = mxRecordReturnFieldsList
 660  
 661  	return res
 662  }
 663  
 664  func NewRecordMX(rm RecordMX) *RecordMX {
 665  	res := rm
 666  	res.returnFields = mxRecordReturnFieldsList
 667  
 668  	return &res
 669  }
 670  
 671  var srvRecordReturnFieldsList = []string{"name", "view", "priority", "weight", "port", "target", "ttl", "use_ttl", "comment", "extattrs", "zone"}
 672  
 673  func NewEmptyRecordSRV() *RecordSRV {
 674  	res := RecordSRV{}
 675  	res.returnFields = srvRecordReturnFieldsList
 676  
 677  	return &res
 678  }
 679  
 680  func NewRecordSRV(rv RecordSRV) *RecordSRV {
 681  	res := rv
 682  	res.returnFields = srvRecordReturnFieldsList
 683  
 684  	return &res
 685  }
 686  
 687  // UnixTime is used to marshall/unmarshall epoch seconds
 688  // presented in different parts of WAPI objects
 689  type UnixTime struct {
 690  	time.Time
 691  }
 692  
 693  func (u *UnixTime) UnmarshalJSON(b []byte) error {
 694  	var timestamp int64
 695  	err := json.Unmarshal(b, &timestamp)
 696  	if err != nil {
 697  		return err
 698  	}
 699  	u.Time = time.Unix(timestamp, 0)
 700  	return nil
 701  }
 702  
 703  func (u UnixTime) MarshalJSON() ([]byte, error) {
 704  	return []byte(fmt.Sprintf("%d", u.Time.Unix())), nil
 705  }
 706  
 707  type Dns struct {
 708  	IBBase      `json:"-"`
 709  	objectType  string
 710  	Ref         string `json:"_ref,omitempty"`
 711  	Ea          EA     `json:"extattrs"`
 712  	Comment     string `json:"comment,omitempty"`
 713  	HostName    string `json:"host_name,omitempty"`
 714  	IPv4Address string `json:"ipv4addr,omitempty"`
 715  	EnableDns   bool   `json:"enable_dns"`
 716  }
 717  
 718  func (d Dns) ObjectType() string {
 719  	return d.objectType
 720  }
 721  
 722  func NewDns(dns Dns) *Dns {
 723  	result := dns
 724  	result.objectType = "member:dns"
 725  	returnFields := []string{"enable_dns", "host_name"}
 726  	result.returnFields = returnFields
 727  	return &result
 728  }
 729  
 730  type Dhcp struct {
 731  	IBBase      `json:"-"`
 732  	objectType  string
 733  	Ref         string `json:"_ref,omitempty"`
 734  	Ea          EA     `json:"extattrs"`
 735  	Comment     string `json:"comment,omitempty"`
 736  	HostName    string `json:"host_name,omitempty"`
 737  	IPv4Address string `json:"ipv4addr,omitempty"`
 738  	EnableDhcp  bool   `json:"enable_dhcp"`
 739  }
 740  
 741  func (d Dhcp) ObjectType() string {
 742  	return d.objectType
 743  }
 744  
 745  func NewDhcp(dhcp Dhcp) *Dhcp {
 746  	result := dhcp
 747  	result.objectType = "member:dhcpproperties"
 748  	returnFields := []string{"enable_dhcp", "host_name"}
 749  	result.returnFields = returnFields
 750  	return &result
 751  }
 752