Skip to content

Commit

Permalink
Migrate from TPR to CRD for the Kubernetes backend
Browse files Browse the repository at this point in the history
  • Loading branch information
gunjan5 committed Aug 15, 2017
1 parent 8ffc50b commit 572437c
Show file tree
Hide file tree
Showing 36 changed files with 879 additions and 760 deletions.
25 changes: 22 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ default: all
all: test
test: ut

K8S_VERSION=1.7.3
K8S_VERSION=v1.7.3
CALICO_BUILD?=calico/go-build
PACKAGE_NAME?=projectcalico/libcalico-go
LOCAL_USER_ID?=$(shell id -u $$USER)
Expand Down Expand Up @@ -51,7 +51,7 @@ run-kubernetes-master: stop-kubernetes-master
docker run \
--net=host --name st-apiserver \
--detach \
gcr.io/google_containers/hyperkube-amd64:v${K8S_VERSION} \
gcr.io/google_containers/hyperkube-amd64:${K8S_VERSION} \
/hyperkube apiserver \
--bind-address=0.0.0.0 \
--insecure-bind-address=0.0.0.0 \
Expand All @@ -69,14 +69,33 @@ run-kubernetes-master: stop-kubernetes-master
docker run \
--net=host --name st-controller-manager \
--detach \
gcr.io/google_containers/hyperkube-amd64:v${K8S_VERSION} \
gcr.io/google_containers/hyperkube-amd64:${K8S_VERSION} \
/hyperkube controller-manager \
--master=127.0.0.1:8080 \
--min-resync-period=3m \
--allocate-node-cidrs=true \
--cluster-cidr=10.10.0.0/16 \
--v=5

# Create CustomResourceDefinition (CRD) for Calico resources
# from the manifest crds.yaml
docker run \
--net=host \
--rm \
-v $(CURDIR):/manifests \
lachlanevenson/k8s-kubectl:${K8S_VERSION} \
--server=http://localhost:8080 \
apply -f manifests/test/crds.yaml

# Create a Node in the API for the tests to use.
docker run \
--net=host \
--rm \
-v $(CURDIR):/manifests \
lachlanevenson/k8s-kubectl:${K8S_VERSION} \
--server=http://localhost:8080 \
apply -f manifests/test/mock-node.yaml

## Stop the local kubernetes master
stop-kubernetes-master:
# Delete the cluster role binding.
Expand Down
8 changes: 4 additions & 4 deletions lib/backend/k8s/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ func (c converter) parsePolicyNameNamespace(name string) (string, error) {

// parsePolicyNameNetworkPolicy extracts the Kubernetes Namespace and NetworkPolicy that backs the given Policy.
func (c converter) parsePolicyNameNetworkPolicy(name string) (string, string, error) {
// Policies backed by NetworkPolicies have form "np.projectcalico.org/<ns_name>.<np_name>"
if !strings.HasPrefix(name, "np.projectcalico.org/") {
// Policies backed by NetworkPolicies have form "knp.default.<ns_name>.<np_name>"
if !strings.HasPrefix(name, "knp.default.") {
// This is not backed by a Kubernetes NetworkPolicy.
return "", "", fmt.Errorf("Policy %s not backed by a NetworkPolicy", name)
}

splits := strings.SplitN(strings.TrimPrefix(name, "np.projectcalico.org/"), ".", 2)
splits := strings.SplitN(strings.TrimPrefix(name, "knp.default."), ".", 2)
if len(splits) != 2 {
return "", "", fmt.Errorf("Name does not include both Namespace and NetworkPolicy: %s", name)
}
Expand Down Expand Up @@ -201,7 +201,7 @@ func (c converter) podToWorkloadEndpoint(pod *kapiv1.Pod) (*model.KVPair, error)
// networkPolicyToPolicy converts a k8s NetworkPolicy to a model.KVPair.
func (c converter) networkPolicyToPolicy(np *extensions.NetworkPolicy) (*model.KVPair, error) {
// Pull out important fields.
policyName := fmt.Sprintf("np.projectcalico.org/%s.%s", np.ObjectMeta.Namespace, np.ObjectMeta.Name)
policyName := fmt.Sprintf("knp.default.%s.%s", np.ObjectMeta.Namespace, np.ObjectMeta.Name)

// We insert all the NetworkPolicy Policies at order 1000.0 after conversion.
// This order might change in future.
Expand Down
18 changes: 9 additions & 9 deletions lib/backend/k8s/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var _ = Describe("Test parsing strings", func() {

It("should parse valid policy names", func() {
// Parse a NetworkPolicy backed Policy.
name := "np.projectcalico.org/Namespace.policyName"
name := "knp.default.Namespace.policyName"
ns, polName, err := c.parsePolicyNameNetworkPolicy(name)
Expect(err).NotTo(HaveOccurred())
Expect(ns).To(Equal("Namespace"))
Expand Down Expand Up @@ -248,7 +248,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
Expect(err).NotTo(HaveOccurred())

// Assert key fields are correct.
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))

// Assert value fields are correct.
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
Expand Down Expand Up @@ -286,7 +286,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
Expect(err).NotTo(HaveOccurred())

// Assert key fields are correct.
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))

// Assert value fields are correct.
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
Expand Down Expand Up @@ -339,7 +339,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
By("parsing the policy", func() {
pol, err = c.networkPolicyToPolicy(&np)
Expect(err).NotTo(HaveOccurred())
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
})

Expand Down Expand Up @@ -412,7 +412,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
By("parsing the policy", func() {
pol, err = c.networkPolicyToPolicy(&np)
Expect(err).NotTo(HaveOccurred())
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
})

Expand Down Expand Up @@ -459,7 +459,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
Expect(err).NotTo(HaveOccurred())

// Assert key fields are correct.
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))

// Assert value fields are correct.
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
Expand Down Expand Up @@ -500,7 +500,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
Expect(err).NotTo(HaveOccurred())

// Assert key fields are correct.
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))

// Assert value fields are correct.
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
Expand Down Expand Up @@ -537,7 +537,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
Expect(err).NotTo(HaveOccurred())

// Assert key fields are correct.
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))

// Assert value fields are correct.
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
Expand Down Expand Up @@ -577,7 +577,7 @@ var _ = Describe("Test NetworkPolicy conversion", func() {
Expect(err).NotTo(HaveOccurred())

// Assert key fields are correct.
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("np.projectcalico.org/default.testPolicy"))
Expect(pol.Key.(model.PolicyKey).Name).To(Equal("knp.default.default.testPolicy"))

// Assert value fields are correct.
Expect(int(*pol.Value.(*model.Policy).Order)).To(Equal(1000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package thirdparty
package custom

import (
"encoding/json"
Expand All @@ -21,70 +21,71 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
)

type GlobalBgpConfigSpec struct {
Name string `json:"name"`
Value string `json:"value"`
}

type GlobalBgpConfig struct {
type GlobalBGPConfig struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ObjectMeta `json:"metadata"`
Metadata metav1.ObjectMeta `json:"metadata"`
Spec GlobalBGPConfigSpec `json:"spec"`
}

Spec GlobalBgpConfigSpec `json:"spec"`
type GlobalBGPConfigSpec struct {
// The reason we have Name field in Spec is because k8s metadata
// name field requires the string to be lowercase, so Name field
// in Spec is to preserve the casing.
Name string `json:"name"`
Value string `json:"value"`
}

type GlobalBgpConfigList struct {
type GlobalBGPConfigList struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ListMeta `json:"metadata"`

Items []GlobalBgpConfig `json:"items"`
Metadata metav1.ListMeta `json:"metadata"`
Items []GlobalBGPConfig `json:"items"`
}

// Required to satisfy Object interface
func (e *GlobalBgpConfig) GetObjectKind() schema.ObjectKind {
func (e *GlobalBGPConfig) GetObjectKind() schema.ObjectKind {
return &e.TypeMeta
}

// Required to satisfy ObjectMetaAccessor interface
func (e *GlobalBgpConfig) GetObjectMeta() metav1.Object {
func (e *GlobalBGPConfig) GetObjectMeta() metav1.Object {
return &e.Metadata
}

// Required to satisfy Object interface
func (el *GlobalBgpConfigList) GetObjectKind() schema.ObjectKind {
func (el *GlobalBGPConfigList) GetObjectKind() schema.ObjectKind {
return &el.TypeMeta
}

// Required to satisfy ListMetaAccessor interface
func (el *GlobalBgpConfigList) GetListMeta() metav1.List {
func (el *GlobalBGPConfigList) GetListMeta() metav1.List {
return &el.Metadata
}

// The code below is used only to work around a known problem with third-party
// resources and ugorji. If/when these issues are resolved, the code below
// should no longer be required.

type GlobalBgpConfigListCopy GlobalBgpConfigList
type GlobalBgpConfigCopy GlobalBgpConfig
type GlobalBGPConfigListCopy GlobalBGPConfigList
type GlobalBGPConfigCopy GlobalBGPConfig

func (g *GlobalBgpConfig) UnmarshalJSON(data []byte) error {
tmp := GlobalBgpConfigCopy{}
func (g *GlobalBGPConfig) UnmarshalJSON(data []byte) error {
tmp := GlobalBGPConfigCopy{}
err := json.Unmarshal(data, &tmp)
if err != nil {
return err
}
tmp2 := GlobalBgpConfig(tmp)
tmp2 := GlobalBGPConfig(tmp)
*g = tmp2
return nil
}

func (l *GlobalBgpConfigList) UnmarshalJSON(data []byte) error {
tmp := GlobalBgpConfigListCopy{}
func (l *GlobalBGPConfigList) UnmarshalJSON(data []byte) error {
tmp := GlobalBGPConfigListCopy{}
err := json.Unmarshal(data, &tmp)
if err != nil {
return err
}
tmp2 := GlobalBgpConfigList(tmp)
tmp2 := GlobalBGPConfigList(tmp)
*l = tmp2
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,76 +12,85 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package thirdparty
package custom

import (
"encoding/json"

"github.com/projectcalico/libcalico-go/lib/api"
"github.com/projectcalico/libcalico-go/lib/net"
"github.com/projectcalico/libcalico-go/lib/scope"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)

// GlobalBgpPeer is the ThirdPartyResource definition of a Calico Global BGP Peer resource in
// BGPPeer is the CustomResourceDefinition of a Calico BGP Peer resource in
// the Kubernetes API.
type GlobalBgpPeer struct {
type BGPPeer struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ObjectMeta `json:"metadata"`
Spec api.BGPPeerSpec `json:"spec"`
Spec BGPPeerSpec `json:"spec"`
}

// GlobalBgpPeerList is a list of Calico Global BGP Peer resources.
type GlobalBgpPeerList struct {
type BGPPeerSpec struct {
api.BGPPeerSpec
Scope scope.Scope `json:"scope"`
Node string `json:"node,omitempty"`
PeerIP net.IP `json:"peerIP"`
}

// BGPPeerList is a list of Calico Global BGP Peer resources.
type BGPPeerList struct {
metav1.TypeMeta `json:",inline"`
Metadata metav1.ListMeta `json:"metadata"`
Items []GlobalBgpPeer `json:"items"`
Items []BGPPeer `json:"items"`
}

// GetObjectKind returns the kind of this object. Required to satisfy Object interface
func (e *GlobalBgpPeer) GetObjectKind() schema.ObjectKind {
func (e *BGPPeer) GetObjectKind() schema.ObjectKind {
return &e.TypeMeta
}

// GetObjectMeta returns the object metadata of this object. Required to satisfy ObjectMetaAccessor interface
func (e *GlobalBgpPeer) GetObjectMeta() metav1.Object {
func (e *BGPPeer) GetObjectMeta() metav1.Object {
return &e.Metadata
}

// GetObjectKind returns the kind of this object. Required to satisfy Object interface
func (el *GlobalBgpPeerList) GetObjectKind() schema.ObjectKind {
func (el *BGPPeerList) GetObjectKind() schema.ObjectKind {
return &el.TypeMeta
}

// GetListMeta returns the list metadata of this object. Required to satisfy ListMetaAccessor interface
func (el *GlobalBgpPeerList) GetListMeta() metav1.List {
func (el *BGPPeerList) GetListMeta() metav1.List {
return &el.Metadata
}

// The code below is used only to work around a known problem with third-party
// resources and ugorji. If/when these issues are resolved, the code below
// should no longer be required.

type GlobalBgpPeerListCopy GlobalBgpPeerList
type GlobalBgpPeerCopy GlobalBgpPeer
type BGPPeerListCopy BGPPeerList
type BGPPeerCopy BGPPeer

func (g *GlobalBgpPeer) UnmarshalJSON(data []byte) error {
tmp := GlobalBgpPeerCopy{}
func (g *BGPPeer) UnmarshalJSON(data []byte) error {
tmp := BGPPeerCopy{}
err := json.Unmarshal(data, &tmp)
if err != nil {
return err
}
tmp2 := GlobalBgpPeer(tmp)
tmp2 := BGPPeer(tmp)
*g = tmp2
return nil
}

func (l *GlobalBgpPeerList) UnmarshalJSON(data []byte) error {
tmp := GlobalBgpPeerListCopy{}
func (l *BGPPeerList) UnmarshalJSON(data []byte) error {
tmp := BGPPeerListCopy{}
err := json.Unmarshal(data, &tmp)
if err != nil {
return err
}
tmp2 := GlobalBgpPeerList(tmp)
tmp2 := BGPPeerList(tmp)
*l = tmp2
return nil
}
Loading

0 comments on commit 572437c

Please sign in to comment.