ipamdata.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package driverapi
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "github.com/docker/docker/libnetwork/types"
  7. )
  8. // MarshalJSON encodes IPAMData into json message
  9. func (i *IPAMData) MarshalJSON() ([]byte, error) {
  10. m := map[string]interface{}{}
  11. m["AddressSpace"] = i.AddressSpace
  12. if i.Pool != nil {
  13. m["Pool"] = i.Pool.String()
  14. }
  15. if i.Gateway != nil {
  16. m["Gateway"] = i.Gateway.String()
  17. }
  18. if i.AuxAddresses != nil {
  19. am := make(map[string]string, len(i.AuxAddresses))
  20. for k, v := range i.AuxAddresses {
  21. am[k] = v.String()
  22. }
  23. m["AuxAddresses"] = am
  24. }
  25. return json.Marshal(m)
  26. }
  27. // UnmarshalJSON decodes a json message into IPAMData
  28. func (i *IPAMData) UnmarshalJSON(data []byte) error {
  29. var (
  30. m map[string]interface{}
  31. err error
  32. )
  33. if err := json.Unmarshal(data, &m); err != nil {
  34. return err
  35. }
  36. i.AddressSpace = m["AddressSpace"].(string)
  37. if v, ok := m["Pool"]; ok {
  38. if i.Pool, err = types.ParseCIDR(v.(string)); err != nil {
  39. return err
  40. }
  41. }
  42. if v, ok := m["Gateway"]; ok {
  43. if i.Gateway, err = types.ParseCIDR(v.(string)); err != nil {
  44. return err
  45. }
  46. }
  47. if v, ok := m["AuxAddresses"]; ok {
  48. b, _ := json.Marshal(v)
  49. var am map[string]string
  50. if err = json.Unmarshal(b, &am); err != nil {
  51. return err
  52. }
  53. i.AuxAddresses = make(map[string]*net.IPNet, len(am))
  54. for k, v := range am {
  55. if i.AuxAddresses[k], err = types.ParseCIDR(v); err != nil {
  56. return err
  57. }
  58. }
  59. }
  60. return nil
  61. }
  62. // Validate checks whether the IPAMData structure contains congruent data
  63. func (i *IPAMData) Validate() error {
  64. var isV6 bool
  65. if i.Pool == nil {
  66. return types.InvalidParameterErrorf("invalid pool")
  67. }
  68. if i.Gateway == nil {
  69. return types.InvalidParameterErrorf("invalid gateway address")
  70. }
  71. isV6 = i.IsV6()
  72. if isV6 && i.Gateway.IP.To4() != nil || !isV6 && i.Gateway.IP.To4() == nil {
  73. return types.InvalidParameterErrorf("incongruent ip versions for pool and gateway")
  74. }
  75. for k, sip := range i.AuxAddresses {
  76. if isV6 && sip.IP.To4() != nil || !isV6 && sip.IP.To4() == nil {
  77. return types.InvalidParameterErrorf("incongruent ip versions for pool and secondary ip address %s", k)
  78. }
  79. }
  80. if !i.Pool.Contains(i.Gateway.IP) {
  81. return types.InvalidParameterErrorf("invalid gateway address (%s) does not belong to the pool (%s)", i.Gateway, i.Pool)
  82. }
  83. for k, sip := range i.AuxAddresses {
  84. if !i.Pool.Contains(sip.IP) {
  85. return types.InvalidParameterErrorf("invalid secondary address %s (%s) does not belong to the pool (%s)", k, i.Gateway, i.Pool)
  86. }
  87. }
  88. return nil
  89. }
  90. // IsV6 returns whether this is an IPv6 IPAMData structure
  91. func (i *IPAMData) IsV6() bool {
  92. return nil == i.Pool.IP.To4()
  93. }
  94. func (i *IPAMData) String() string {
  95. return fmt.Sprintf("AddressSpace: %s\nPool: %v\nGateway: %v\nAddresses: %v", i.AddressSpace, i.Pool, i.Gateway, i.AuxAddresses)
  96. }