Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: E2E Framework [Kubernetes steps] [3/6] #2529

Merged
merged 4 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.28.3 // indirect
k8s.io/component-base v0.28.5 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
Expand All @@ -132,6 +132,7 @@ require (
require (
golang.org/x/sync v0.6.0
gotest.tools/v3 v3.5.1
k8s.io/kubectl v0.28.5
sigs.k8s.io/yaml v1.4.0
)

Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -464,14 +464,16 @@ k8s.io/apimachinery v0.28.5 h1:EEj2q1qdTcv2p5wl88KavAn3VlFRjREgRu8Sm/EuMPY=
k8s.io/apimachinery v0.28.5/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
k8s.io/client-go v0.28.5 h1:6UNmc33vuJhh3+SAOEKku3QnKa+DtPKGnhO2MR0IEbk=
k8s.io/client-go v0.28.5/go.mod h1:+pt086yx1i0HAlHzM9S+RZQDqdlzuXFl4hY01uhpcpA=
k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI=
k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8=
k8s.io/component-base v0.28.5 h1:uFCW7USa8Fpme8dVtn2ZrdVaUPBRDwYJ+kNrV9OO1Cc=
k8s.io/component-base v0.28.5/go.mod h1:gw2d8O28okS9RrsPuJnD2mFl2It0HH9neHiGi2xoXcY=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.120.0 h1:z+q5mfovBj1fKFxiRzsa2DsJLPIVMk/KFL81LMOfK+8=
k8s.io/klog/v2 v2.120.0/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/kubectl v0.28.5 h1:jq8xtiCCZPR8Cl/Qe1D7bLU0h8KtcunwfROqIekCUeU=
k8s.io/kubectl v0.28.5/go.mod h1:9WiwzqeKs3vLiDtEQPbjhqqysX+BIVMLt7C7gN+T5w8=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
Expand Down
162 changes: 162 additions & 0 deletions test/e2e/framework/kubernetes/create-agnhost-statefulset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package k8s

import (
"context"
"fmt"
"strconv"
"time"

appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)

var ErrLabelMissingFromPod = fmt.Errorf("label missing from pod")

const (
AgnhostHTTPPort = 80
AgnhostReplicas = 1

defaultTimeoutSeconds = 300
defaultRetryDelay = 5 * time.Second
defaultRetryAttempts = 60
defaultHTTPClientTimeout = 2 * time.Second
)

type CreateAgnhostStatefulSet struct {
AgnhostName string
AgnhostNamespace string
KubeConfigFilePath string
}

func (c *CreateAgnhostStatefulSet) Run() error {
config, err := clientcmd.BuildConfigFromFlags("", c.KubeConfigFilePath)
if err != nil {
return fmt.Errorf("error building kubeconfig: %w", err)
}

clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return fmt.Errorf("error creating Kubernetes client: %w", err)
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeoutSeconds*time.Second)
defer cancel()

agnhostStatefulest := c.getAgnhostDeployment()

err = CreateResource(ctx, agnhostStatefulest, clientset)
if err != nil {
return fmt.Errorf("error agnhost component: %w", err)
}

selector, exists := agnhostStatefulest.Spec.Selector.MatchLabels["app"]
if !exists {
return fmt.Errorf("missing label \"app=%s\" from agnhost statefulset: %w", c.AgnhostName, ErrLabelMissingFromPod)
}

labelSelector := fmt.Sprintf("app=%s", selector)
err = WaitForPodReady(ctx, clientset, c.AgnhostNamespace, labelSelector)
if err != nil {
return fmt.Errorf("error waiting for agnhost pod to be ready: %w", err)
}

return nil
}

func (c *CreateAgnhostStatefulSet) Prevalidate() error {
return nil
}

func (c *CreateAgnhostStatefulSet) Postvalidate() error {
return nil
}

func (c *CreateAgnhostStatefulSet) getAgnhostDeployment() *appsv1.StatefulSet {
reps := int32(AgnhostReplicas)

return &appsv1.StatefulSet{
TypeMeta: metaV1.TypeMeta{
Kind: "Deployment",
APIVersion: "apps/v1",
},
ObjectMeta: metaV1.ObjectMeta{
Name: c.AgnhostName,
Namespace: c.AgnhostNamespace,
},
Spec: appsv1.StatefulSetSpec{
Replicas: &reps,
Selector: &metaV1.LabelSelector{
MatchLabels: map[string]string{
"app": c.AgnhostName,
"k8s-app": "agnhost",
},
},
Template: v1.PodTemplateSpec{
ObjectMeta: metaV1.ObjectMeta{
Labels: map[string]string{
"app": c.AgnhostName,
"k8s-app": "agnhost",
},
Annotations: map[string]string{
"policy.cilium.io/proxy-visibility": "<Egress/53/UDP/DNS>",
},
},

Spec: v1.PodSpec{
Affinity: &v1.Affinity{
PodAntiAffinity: &v1.PodAntiAffinity{
// prefer an even spread across the cluster to avoid scheduling on the same node
PreferredDuringSchedulingIgnoredDuringExecution: []v1.WeightedPodAffinityTerm{
{
Weight: MaxAffinityWeight,
PodAffinityTerm: v1.PodAffinityTerm{
TopologyKey: "kubernetes.io/hostname",
LabelSelector: &metaV1.LabelSelector{
MatchLabels: map[string]string{
"k8s-app": "agnhost",
},
},
},
},
},
},
},
Containers: []v1.Container{
{
Name: c.AgnhostName,
Image: "acnpublic.azurecr.io/agnhost:2.40",
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
"memory": resource.MustParse("20Mi"),
},
Limits: v1.ResourceList{
"memory": resource.MustParse("20Mi"),
},
},
Command: []string{
"/agnhost",
},
Args: []string{
"serve-hostname",
"--http",
"--port",
strconv.Itoa(AgnhostHTTPPort),
},

Ports: []v1.ContainerPort{
{
ContainerPort: AgnhostHTTPPort,
},
},
Env: []v1.EnvVar{},
},
},
},
},
},
}
}
Loading
Loading