github.com/moby/docker@v26.1.3+incompatible/libnetwork/drivers/windows/windows_store.go (about)

     1  //go:build windows
     2  
     3  package windows
     4  
     5  import (
     6  	"context"
     7  	"encoding/json"
     8  	"fmt"
     9  	"net"
    10  
    11  	"github.com/containerd/log"
    12  	"github.com/docker/docker/libnetwork/datastore"
    13  	"github.com/docker/docker/libnetwork/netlabel"
    14  	"github.com/docker/docker/libnetwork/types"
    15  )
    16  
    17  const (
    18  	windowsPrefix         = "windows"
    19  	windowsEndpointPrefix = "windows-endpoint"
    20  )
    21  
    22  func (d *driver) initStore(option map[string]interface{}) error {
    23  	if data, ok := option[netlabel.LocalKVClient]; ok {
    24  		var ok bool
    25  		d.store, ok = data.(*datastore.Store)
    26  		if !ok {
    27  			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
    28  		}
    29  
    30  		err := d.populateNetworks()
    31  		if err != nil {
    32  			return err
    33  		}
    34  
    35  		err = d.populateEndpoints()
    36  		if err != nil {
    37  			return err
    38  		}
    39  	}
    40  
    41  	return nil
    42  }
    43  
    44  func (d *driver) populateNetworks() error {
    45  	kvol, err := d.store.List(&networkConfiguration{Type: d.name})
    46  	if err != nil && err != datastore.ErrKeyNotFound {
    47  		return fmt.Errorf("failed to get windows network configurations from store: %v", err)
    48  	}
    49  
    50  	// It's normal for network configuration state to be empty. Just return.
    51  	if err == datastore.ErrKeyNotFound {
    52  		return nil
    53  	}
    54  
    55  	for _, kvo := range kvol {
    56  		ncfg := kvo.(*networkConfiguration)
    57  		if ncfg.Type != d.name {
    58  			continue
    59  		}
    60  		d.createNetwork(ncfg)
    61  		log.G(context.TODO()).Debugf("Network  %v (%.7s) restored", d.name, ncfg.ID)
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  func (d *driver) populateEndpoints() error {
    68  	kvol, err := d.store.List(&hnsEndpoint{Type: d.name})
    69  	if err != nil && err != datastore.ErrKeyNotFound {
    70  		return fmt.Errorf("failed to get endpoints from store: %v", err)
    71  	}
    72  
    73  	if err == datastore.ErrKeyNotFound {
    74  		return nil
    75  	}
    76  
    77  	for _, kvo := range kvol {
    78  		ep := kvo.(*hnsEndpoint)
    79  		if ep.Type != d.name {
    80  			continue
    81  		}
    82  		n, ok := d.networks[ep.nid]
    83  		if !ok {
    84  			log.G(context.TODO()).Debugf("Network (%.7s) not found for restored endpoint (%.7s)", ep.nid, ep.id)
    85  			log.G(context.TODO()).Debugf("Deleting stale endpoint (%.7s) from store", ep.id)
    86  			if err := d.storeDelete(ep); err != nil {
    87  				log.G(context.TODO()).Debugf("Failed to delete stale endpoint (%.7s) from store", ep.id)
    88  			}
    89  			continue
    90  		}
    91  		n.endpoints[ep.id] = ep
    92  		log.G(context.TODO()).Debugf("Endpoint (%.7s) restored to network (%.7s)", ep.id, ep.nid)
    93  	}
    94  
    95  	return nil
    96  }
    97  
    98  func (d *driver) storeUpdate(kvObject datastore.KVObject) error {
    99  	if d.store == nil {
   100  		log.G(context.TODO()).Warnf("store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...))
   101  		return nil
   102  	}
   103  
   104  	if err := d.store.PutObjectAtomic(kvObject); err != nil {
   105  		return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err)
   106  	}
   107  
   108  	return nil
   109  }
   110  
   111  func (d *driver) storeDelete(kvObject datastore.KVObject) error {
   112  	if d.store == nil {
   113  		log.G(context.TODO()).Debugf("store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...))
   114  		return nil
   115  	}
   116  
   117  	return d.store.DeleteObject(kvObject)
   118  }
   119  
   120  func (ncfg *networkConfiguration) MarshalJSON() ([]byte, error) {
   121  	nMap := make(map[string]interface{})
   122  
   123  	nMap["ID"] = ncfg.ID
   124  	nMap["Type"] = ncfg.Type
   125  	nMap["Name"] = ncfg.Name
   126  	nMap["HnsID"] = ncfg.HnsID
   127  	nMap["VLAN"] = ncfg.VLAN
   128  	nMap["VSID"] = ncfg.VSID
   129  	nMap["DNSServers"] = ncfg.DNSServers
   130  	nMap["DNSSuffix"] = ncfg.DNSSuffix
   131  	nMap["SourceMac"] = ncfg.SourceMac
   132  	nMap["NetworkAdapterName"] = ncfg.NetworkAdapterName
   133  
   134  	return json.Marshal(nMap)
   135  }
   136  
   137  func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error {
   138  	var (
   139  		err  error
   140  		nMap map[string]interface{}
   141  	)
   142  
   143  	if err = json.Unmarshal(b, &nMap); err != nil {
   144  		return err
   145  	}
   146  
   147  	ncfg.ID = nMap["ID"].(string)
   148  	ncfg.Type = nMap["Type"].(string)
   149  	ncfg.Name = nMap["Name"].(string)
   150  	ncfg.HnsID = nMap["HnsID"].(string)
   151  	ncfg.VLAN = uint(nMap["VLAN"].(float64))
   152  	ncfg.VSID = uint(nMap["VSID"].(float64))
   153  	ncfg.DNSServers = nMap["DNSServers"].(string)
   154  	ncfg.DNSSuffix = nMap["DNSSuffix"].(string)
   155  	ncfg.SourceMac = nMap["SourceMac"].(string)
   156  	ncfg.NetworkAdapterName = nMap["NetworkAdapterName"].(string)
   157  	return nil
   158  }
   159  
   160  func (ncfg *networkConfiguration) Key() []string {
   161  	return []string{windowsPrefix + ncfg.Type, ncfg.ID}
   162  }
   163  
   164  func (ncfg *networkConfiguration) KeyPrefix() []string {
   165  	return []string{windowsPrefix + ncfg.Type}
   166  }
   167  
   168  func (ncfg *networkConfiguration) Value() []byte {
   169  	b, err := json.Marshal(ncfg)
   170  	if err != nil {
   171  		return nil
   172  	}
   173  	return b
   174  }
   175  
   176  func (ncfg *networkConfiguration) SetValue(value []byte) error {
   177  	return json.Unmarshal(value, ncfg)
   178  }
   179  
   180  func (ncfg *networkConfiguration) Index() uint64 {
   181  	return ncfg.dbIndex
   182  }
   183  
   184  func (ncfg *networkConfiguration) SetIndex(index uint64) {
   185  	ncfg.dbIndex = index
   186  	ncfg.dbExists = true
   187  }
   188  
   189  func (ncfg *networkConfiguration) Exists() bool {
   190  	return ncfg.dbExists
   191  }
   192  
   193  func (ncfg *networkConfiguration) Skip() bool {
   194  	return false
   195  }
   196  
   197  func (ncfg *networkConfiguration) New() datastore.KVObject {
   198  	return &networkConfiguration{Type: ncfg.Type}
   199  }
   200  
   201  func (ncfg *networkConfiguration) CopyTo(o datastore.KVObject) error {
   202  	dstNcfg := o.(*networkConfiguration)
   203  	*dstNcfg = *ncfg
   204  	return nil
   205  }
   206  
   207  func (ep *hnsEndpoint) MarshalJSON() ([]byte, error) {
   208  	epMap := make(map[string]interface{})
   209  	epMap["id"] = ep.id
   210  	epMap["nid"] = ep.nid
   211  	epMap["Type"] = ep.Type
   212  	epMap["profileID"] = ep.profileID
   213  	epMap["MacAddress"] = ep.macAddress.String()
   214  	if ep.addr.IP != nil {
   215  		epMap["Addr"] = ep.addr.String()
   216  	}
   217  	if ep.gateway != nil {
   218  		epMap["gateway"] = ep.gateway.String()
   219  	}
   220  	epMap["epOption"] = ep.epOption
   221  	epMap["epConnectivity"] = ep.epConnectivity
   222  	epMap["PortMapping"] = ep.portMapping
   223  
   224  	return json.Marshal(epMap)
   225  }
   226  
   227  func (ep *hnsEndpoint) UnmarshalJSON(b []byte) error {
   228  	var (
   229  		err   error
   230  		epMap map[string]interface{}
   231  	)
   232  
   233  	if err = json.Unmarshal(b, &epMap); err != nil {
   234  		return fmt.Errorf("Failed to unmarshal to endpoint: %v", err)
   235  	}
   236  	if v, ok := epMap["MacAddress"]; ok {
   237  		if ep.macAddress, err = net.ParseMAC(v.(string)); err != nil {
   238  			return types.InternalErrorf("failed to decode endpoint MAC address (%s) after json unmarshal: %v", v.(string), err)
   239  		}
   240  	}
   241  	if v, ok := epMap["Addr"]; ok {
   242  		if ep.addr, err = types.ParseCIDR(v.(string)); err != nil {
   243  			log.G(context.TODO()).Warnf("failed to decode endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err)
   244  		}
   245  	}
   246  	if v, ok := epMap["gateway"]; ok {
   247  		ep.gateway = net.ParseIP(v.(string))
   248  	}
   249  	ep.id = epMap["id"].(string)
   250  	ep.Type = epMap["Type"].(string)
   251  	ep.nid = epMap["nid"].(string)
   252  	ep.profileID = epMap["profileID"].(string)
   253  	d, _ := json.Marshal(epMap["epOption"])
   254  	if err := json.Unmarshal(d, &ep.epOption); err != nil {
   255  		log.G(context.TODO()).Warnf("Failed to decode endpoint container config %v", err)
   256  	}
   257  	d, _ = json.Marshal(epMap["epConnectivity"])
   258  	if err := json.Unmarshal(d, &ep.epConnectivity); err != nil {
   259  		log.G(context.TODO()).Warnf("Failed to decode endpoint external connectivity configuration %v", err)
   260  	}
   261  	d, _ = json.Marshal(epMap["PortMapping"])
   262  	if err := json.Unmarshal(d, &ep.portMapping); err != nil {
   263  		log.G(context.TODO()).Warnf("Failed to decode endpoint port mapping %v", err)
   264  	}
   265  
   266  	return nil
   267  }
   268  
   269  func (ep *hnsEndpoint) Key() []string {
   270  	return []string{windowsEndpointPrefix + ep.Type, ep.id}
   271  }
   272  
   273  func (ep *hnsEndpoint) KeyPrefix() []string {
   274  	return []string{windowsEndpointPrefix + ep.Type}
   275  }
   276  
   277  func (ep *hnsEndpoint) Value() []byte {
   278  	b, err := json.Marshal(ep)
   279  	if err != nil {
   280  		return nil
   281  	}
   282  	return b
   283  }
   284  
   285  func (ep *hnsEndpoint) SetValue(value []byte) error {
   286  	return json.Unmarshal(value, ep)
   287  }
   288  
   289  func (ep *hnsEndpoint) Index() uint64 {
   290  	return ep.dbIndex
   291  }
   292  
   293  func (ep *hnsEndpoint) SetIndex(index uint64) {
   294  	ep.dbIndex = index
   295  	ep.dbExists = true
   296  }
   297  
   298  func (ep *hnsEndpoint) Exists() bool {
   299  	return ep.dbExists
   300  }
   301  
   302  func (ep *hnsEndpoint) Skip() bool {
   303  	return false
   304  }
   305  
   306  func (ep *hnsEndpoint) New() datastore.KVObject {
   307  	return &hnsEndpoint{Type: ep.Type}
   308  }
   309  
   310  func (ep *hnsEndpoint) CopyTo(o datastore.KVObject) error {
   311  	dstEp := o.(*hnsEndpoint)
   312  	*dstEp = *ep
   313  	return nil
   314  }