func validateBlockValue(kvp *model.KVPair) error {
	if kvp.Value.(*model.AllocationBlock).HostAffinity != nil {
		return goerrors.New("AllocationBlock.HostAffinity is deprecated, please use Affinity instead.")
	}
	return nil
}
validateBlockValue validates the AllocationBlock fields (specifically Affinity) to
make sure the deprecated HostAffinity field is not used.
package compat
import (
	"encoding/json"
	goerrors "errors"
	log "github.com/sirupsen/logrus"
	"context"
	"github.com/projectcalico/api/pkg/lib/numorstring"
	"github.com/projectcalico/libcalico-go/lib/backend/api"
	"github.com/projectcalico/libcalico-go/lib/backend/model"
	"github.com/projectcalico/libcalico-go/lib/errors"
	"github.com/projectcalico/libcalico-go/lib/net"
)
type ModelAdaptor struct {
	client api.Client
}
var _ api.Client = (*ModelAdaptor)(nil)
func NewAdaptor(c api.Client) *ModelAdaptor {
	return &ModelAdaptor{client: c}
}
func (c *ModelAdaptor) EnsureInitialized() error {
	return c.client.EnsureInitialized()
}
func (c *ModelAdaptor) Clean() error {
	return c.client.Clean()
}
func (c *ModelAdaptor) Create(ctx context.Context, d *model.KVPair) (*model.KVPair, error) {
	var err error
	switch k := d.Key.(type) {
	case model.ProfileKey:
		t, l, r := ToTagsLabelsRules(d)
		if t, err = c.client.Create(ctx, t); err != nil {
			return nil, err
		} else if _, err := c.client.Create(ctx, l); err != nil {
			return nil, err
		} else if _, err := c.client.Create(ctx, r); err != nil {
			return nil, err
		} else {
			d.Revision = t.Revision
			return d, nil
		}
	case model.NodeKey:
		p, o := toNodeComponents(d)
		if p, err = c.client.Create(ctx, p); err != nil {
			return nil, err
		}
		if err = c.applyOrDeleteSubcomponents(ctx, o); err != nil {
			return nil, err
		}
		d.Revision = p.Revision
		return d, nil
	case model.BlockKey:
		if err = validateBlockValue(d); err != nil {
			return nil, err
		}
		b, err := c.client.Create(ctx, d)
		if err != nil {
			return nil, err
		}
		d.Revision = b.Revision
		return d, nil
	case model.GlobalBGPConfigKey:
		nd := toDatastoreGlobalBGPConfig(*d)
		b, err := c.client.Create(ctx, nd)
		if err != nil {
			return nil, errors.UpdateErrorIdentifier(err, k)
		}
		d.Revision = b.Revision
		return d, nil
	default:
		return c.client.Create(ctx, d)
	}
}
func (c *ModelAdaptor) Update(ctx context.Context, d *model.KVPair) (*model.KVPair, error) {
	var err error
	switch d.Key.(type) {
	case model.ProfileKey:
		t, l, r := ToTagsLabelsRules(d)
		if t, err = c.client.Update(ctx, t); err != nil {
			return nil, err
		} else if _, err := c.client.Apply(ctx, l); err != nil {
			return nil, err
		} else if _, err := c.client.Apply(ctx, r); err != nil {
			return nil, err
		} else {
			d.Revision = t.Revision
			return d, nil
		}
	case model.NodeKey:
		p, o := toNodeComponents(d)
		if p, err = c.client.Update(ctx, p); err != nil {
			return nil, err
		}
		if err = c.applyOrDeleteSubcomponents(ctx, o); err != nil {
			return nil, err
		}
		d.Revision = p.Revision
		return d, nil
	case model.BlockKey:
		if err = validateBlockValue(d); err != nil {
			return nil, err
		}
		b, err := c.client.Update(ctx, d)
		if err != nil {
			return nil, err
		}
		d.Revision = b.Revision
		return d, nil
	case model.GlobalBGPConfigKey:
		nd := toDatastoreGlobalBGPConfig(*d)
		b, err := c.client.Update(ctx, nd)
		if err != nil {
			return nil, errors.UpdateErrorIdentifier(err, d.Key)
		}
		d.Revision = b.Revision
		return d, nil
	default:
		return c.client.Update(ctx, d)
	}
}
func (c *ModelAdaptor) Apply(ctx context.Context, d *model.KVPair) (*model.KVPair, error) {
	var err error
	switch d.Key.(type) {
	case model.ProfileKey:
		t, l, r := ToTagsLabelsRules(d)
		if t, err = c.client.Apply(ctx, t); err != nil {
			return nil, err
		} else if _, err := c.client.Apply(ctx, l); err != nil {
			return nil, err
		} else if _, err := c.client.Apply(ctx, r); err != nil {
			return nil, errors.UpdateErrorIdentifier(err, d.Key)
		} else {
			d.Revision = t.Revision
			return d, nil
		}
	case model.NodeKey:
		p, o := toNodeComponents(d)
		if p, err = c.client.Apply(ctx, p); err != nil {
			return nil, err
		}
		if err = c.applyOrDeleteSubcomponents(context.Background(), o); err != nil {
			return nil, err
		}
		d.Revision = p.Revision
		return d, nil
	case model.BlockKey:
		if err = validateBlockValue(d); err != nil {
			return nil, err
		}
		b, err := c.client.Apply(ctx, d)
		if err != nil {
			return nil, err
		}
		d.Revision = b.Revision
		return d, nil
	case model.GlobalBGPConfigKey:
		nd := toDatastoreGlobalBGPConfig(*d)
		b, err := c.client.Apply(ctx, nd)
		if err != nil {
			return nil, errors.UpdateErrorIdentifier(err, d.Key)
		}
		d.Revision = b.Revision
		return d, nil
	default:
		return c.client.Apply(ctx, d)
	}
}
func (c *ModelAdaptor) Delete(ctx context.Context, k model.Key, rev string) (*model.KVPair, error) {
	var err error
	switch key := k.(type) {
	case model.NodeKey:
		p, o := toNodeDeleteComponents(key)
		if err = c.applyOrDeleteSubcomponents(ctx, o); err != nil {
			return nil, err
		}
		if _, err = c.client.Delete(ctx, p.Key, rev); err != nil {
			return nil, err
		}
		return nil, nil
	case model.GlobalBGPConfigKey:
		nd := toDatastoreGlobalBGPConfig(model.KVPair{Key: k})
		_, err := c.client.Delete(ctx, nd.Key, rev)
		return nil, errors.UpdateErrorIdentifier(err, k)
	default:
		return c.client.Delete(ctx, k, rev)
	}
}
func (c *ModelAdaptor) DeleteKVP(ctx context.Context, kvp *model.KVPair) (*model.KVPair, error) {
	return nil, errors.ErrorOperationNotSupported{Operation: "DeleteKVP", Identifier: kvp.Key}
}
func (c *ModelAdaptor) Get(ctx context.Context, k model.Key, rev string) (*model.KVPair, error) {
	switch kt := k.(type) {
	case model.ProfileKey:
		return c.getProfile(ctx, k)
	case model.NodeKey:
		return c.getNode(ctx, kt)
	case model.BlockKey:
		return c.getBlock(ctx, k, rev)
	case model.GlobalBGPConfigKey:
		nk := toDatastoreGlobalBGPConfigKey(kt)
		if kvp, err := c.client.Get(ctx, nk, rev); err != nil {
			return nil, errors.UpdateErrorIdentifier(err, k)
		} else {
			return fromDatastoreGlobalBGPConfig(*kvp), nil
		}
	default:
		return c.client.Get(ctx, k, rev)
	}
}
func (c *ModelAdaptor) List(ctx context.Context, l model.ListInterface, rev string) (*model.KVPairList, error) {
	switch lt := l.(type) {
	case model.NodeListOptions:
		return c.listNodes(ctx, lt)
	case model.BlockListOptions:
		return c.listBlock(ctx, lt)
	case model.GlobalBGPConfigListOptions:
		nl := toDatastoreGlobalBGPConfigList(lt)
		if kvps, err := c.client.List(ctx, nl, ""); err != nil {
			return nil, errors.UpdateErrorIdentifier(err, l)
		} else {
			for i, kvp := range kvps.KVPairs {
				kvps.KVPairs[i] = fromDatastoreGlobalBGPConfig(*kvp)
			}
			return kvps, nil
		}
	default:
		return c.client.List(ctx, l, "")
	}
}
func (c *ModelAdaptor) Watch(ctx context.Context, l model.ListInterface, revision string) (api.WatchInterface, error) {
	return c.client.Watch(ctx, l, revision)
}
func (c *ModelAdaptor) getProfile(ctx context.Context, k model.Key) (*model.KVPair, error) {
	var t, l, r *model.KVPair
	var err error
	pk := k.(model.ProfileKey)
	if t, err = c.client.Get(ctx, model.ProfileTagsKey{pk}, ""); err != nil {
		return nil, err
	}
	d := model.KVPair{
		Key: k,
		Value: &model.Profile{
			Tags: t.Value.([]string),
		},
		Revision: t.Revision,
	}
	p := d.Value.(*model.Profile)
	if l, err = c.client.Get(ctx, model.ProfileLabelsKey{pk}, ""); err == nil {
		p.Labels = l.Value.(map[string]string)
	}
	if r, err = c.client.Get(ctx, model.ProfileRulesKey{pk}, ""); err == nil {
		p.Rules = *r.Value.(*model.ProfileRules)
	}
	return &d, nil
}
func (c *ModelAdaptor) getBlock(ctx context.Context, k model.Key, rev string) (*model.KVPair, error) {
	bk := k.(model.BlockKey)
	v, err := c.client.Get(ctx, model.BlockKey{CIDR: bk.CIDR}, rev)
	if err != nil {
		return nil, err
	}
	return ensureBlockAffinity(v), nil
}
func (c *ModelAdaptor) getNode(ctx context.Context, nk model.NodeKey) (*model.KVPair, error) {
	var err error
	if _, err = c.client.Get(ctx, model.HostMetadataKey{nk.Hostname}, ""); err != nil {
		return nil, err
	}
	nv := model.Node{}
	err = c.getNodeSubcomponents(ctx, nk, &nv)
	if err != nil {
		return nil, err
	}
	return &model.KVPair{Key: nk, Value: &nv}, nil
}