From 583620d379e802bc096d0fc5d3c3a02c7d4becf7 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 10 Nov 2023 23:52:16 +0530 Subject: [PATCH 01/22] Kubernetes --- .dockerconfigjson | 9 ++ Dockerfile | 39 +++++++ README.md | 37 ++++++- kubernetes/alb-ingress-iam-policy.json | 140 +++++++++++++++++++++++++ kubernetes/deployment.yml | 53 ++++++++++ kubernetes/docker-image-secret.yaml | 9 ++ main.go | 9 +- 7 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 .dockerconfigjson create mode 100644 Dockerfile create mode 100644 kubernetes/alb-ingress-iam-policy.json create mode 100644 kubernetes/deployment.yml create mode 100644 kubernetes/docker-image-secret.yaml diff --git a/.dockerconfigjson b/.dockerconfigjson new file mode 100644 index 0000000..1ab5294 --- /dev/null +++ b/.dockerconfigjson @@ -0,0 +1,9 @@ +{ + "auths": + { + "ghcr.io": + { + "auth":"aGFyc2hzaW5naHZpOmdocF9QME8wYmtWSEp1V3lrNmdOVzZCYVc4Q0V6cnlLUWgxdFJuRUk=" + } + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..26f5619 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +############################ +# STEP 1 build executable binary +############################ +FROM golang:alpine AS builder +# Install git. +# Git is required for fetching the dependencies. +RUN apk update && apk add --no-cache 'git=~2' + +# Install dependencies +ENV GO111MODULE=on +WORKDIR $GOPATH/src/packages/goginapp/ +COPY . . + +# Fetch dependencies. +# Using go get. +RUN go get -d -v + +# Build the binary. +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /go/main . + +############################ +# STEP 2 build a small image +############################ +FROM alpine + +WORKDIR / + +# Copy our static executable. +COPY --from=builder /go/main /go/main +# COPY public /go/public + +ENV PORT 8080 +ENV GIN_MODE debug +EXPOSE 8080 + +WORKDIR /go + +# Run the Go Gin binary. +ENTRYPOINT ["/go/main"] diff --git a/README.md b/README.md index 62033df..55d8f75 100644 --- a/README.md +++ b/README.md @@ -12,4 +12,39 @@ - Linkedin Learning (kubernetes, golang courses) - udemy hnsr course db - https://go.dev/doc/tutorial/web-service-gin -- https://dev.to/ramu_mangalarapu/building-rest-apis-in-golang-go-gin-with-persistence-database-postgres-4616 \ No newline at end of file +- https://dev.to/ramu_mangalarapu/building-rest-apis-in-golang-go-gin-with-persistence-database-postgres-4616 +- https://www.coding-bootcamps.com/blog/build-containerized-applications-with-golang-on-kubernetes.html +- https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html +- https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ +- https://dev.to/asizikov/using-github-container-registry-with-kubernetes-38fb ghcr.io kubernetes +- https://aws.amazon.com/blogs/containers/using-alb-ingress-controller-with-amazon-eks-on-fargate/ fargarte exose services + +## TODOS + +- Golang API +- Deploy go API to Kubernetes + +- test autoscaling using Apache benchmark + +- setup CI/CD pipeline +- Connect external postgress to it +- deploy postgress to Kubernetes +- autoscale postgress deployment + +## AWS Resources created (tags: pingsafe-test) +- EKS IAM Role +- EKS Cluster +- ECS Cluster +- vpc subnets + +docker login -u AWS -p $(aws ecr get-login-password --region ap-south-1) 194505915562.dkr.ecr.ap-south-1.amazonaws.com + + +## Build docker image for eks faragete +// login ghcr docker +export CR_PAT=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 +echo $CR_PAT | docker login ghcr.io -u harshsinghvi --password-stdin + +docker buildx build --platform=linux/amd64 -t ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest . + +docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest diff --git a/kubernetes/alb-ingress-iam-policy.json b/kubernetes/alb-ingress-iam-policy.json new file mode 100644 index 0000000..b5b6bf0 --- /dev/null +++ b/kubernetes/alb-ingress-iam-policy.json @@ -0,0 +1,140 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "acm:DescribeCertificate", + "acm:ListCertificates", + "acm:GetCertificate" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CreateSecurityGroup", + "ec2:CreateTags", + "ec2:DeleteTags", + "ec2:DeleteSecurityGroup", + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeInstances", + "ec2:DescribeInstanceStatus", + "ec2:DescribeInternetGateways", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeTags", + "ec2:DescribeVpcs", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:RevokeSecurityGroupIngress" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:AddTags", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:CreateTargetGroup", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeleteRule", + "elasticloadbalancing:DeleteTargetGroup", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:ModifyRule", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:RemoveTags", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:SetWebAcl" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "iam:CreateServiceLinkedRole", + "iam:GetServerCertificate", + "iam:ListServerCertificates" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "cognito-idp:DescribeUserPoolClient" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "waf-regional:GetWebACLForResource", + "waf-regional:GetWebACL", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "tag:GetResources", + "tag:TagResources" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "waf:GetWebACL" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "shield:DescribeProtection", + "shield:GetSubscriptionState", + "shield:DeleteProtection", + "shield:CreateProtection", + "shield:DescribeSubscription", + "shield:ListProtections" + ], + "Resource": "*" + } + ] +} diff --git a/kubernetes/deployment.yml b/kubernetes/deployment.yml new file mode 100644 index 0000000..a86b04e --- /dev/null +++ b/kubernetes/deployment.yml @@ -0,0 +1,53 @@ +--- +apiVersion: apps/v1 +kind: Deployment # Type of Kubernetes resource +metadata: + name: go-todo-api # Name of the Kubernetes resource +spec: + replicas: 3 # Number of pods to run at any given time + selector: + matchLabels: + app: go-todo-api # This deployment applies to any Pods matching the specified label + template: # This deployment will create a set of pods using the configurations in this template + metadata: + labels: # The labels that will be applied to all of the pods in this deployment + app: go-todo-api + spec: # Spec for the container which will run in the Pod + imagePullSecrets: + - name: dockerconfigjson-github-com + containers: + - name: go-todo-api + image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest + imagePullPolicy: Always # IfNotPresent + ports: + - containerPort: 8080 # Should match the port number that the Go application listens on + livenessProbe: # To check the health of the Pod + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 15 + timeoutSeconds: 5 + readinessProbe: # To check if the Pod is ready to serve traffic or not + httpGet: + path: /readiness + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 1 +# Not for AWS Fargate +--- +apiVersion: v1 +kind: Service +metadata: + name: go-todo-api-loadbalancer +spec: + type: LoadBalancer + selector: + app: go-todo-api + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + diff --git a/kubernetes/docker-image-secret.yaml b/kubernetes/docker-image-secret.yaml new file mode 100644 index 0000000..6c8de9a --- /dev/null +++ b/kubernetes/docker-image-secret.yaml @@ -0,0 +1,9 @@ +kind: Secret +type: kubernetes.io/dockerconfigjson +apiVersion: v1 +metadata: + name: dockerconfigjson-github-com + labels: + app: app-name +data: + .dockerconfigjson: eyAiYXV0aHMiOiB7ICJnaGNyLmlvIjogeyAiYXV0aCI6ImFHRnljMmh6YVc1bmFIWnBPbWRvY0Y5UU1FOHdZbXRXU0VwMVYzbHJObWRPVnpaQ1lWYzRRMFY2Y25sTFVXZ3hkRkp1UlVrPSIgfSB9IH0= diff --git a/main.go b/main.go index 49c1099..a3d31a7 100644 --- a/main.go +++ b/main.go @@ -104,12 +104,19 @@ func deleteTodos(c *gin.Context){ c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no ID"}) } +func healthAndReadinessHandler(c *gin.Context){ + c.IndentedJSON(http.StatusOK, gin.H {"message": "OK"}) +} + func main() { router := gin.Default() router.GET("/todos", getTodos) router.POST("/todos", postTodos) router.PUT("/todos/:id", updateTodos) router.DELETE("/todos/:id", deleteTodos) + + router.GET("/health", healthAndReadinessHandler) + router.GET("/readiness", healthAndReadinessHandler) - router.Run("localhost:8080") + router.Run(":8080") } From da6f49209076632f5b564b6f77a609a03e5b7b09 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Sat, 11 Nov 2023 02:18:01 +0530 Subject: [PATCH 02/22] Kubernetes working --- README.md | 3 + ...policy.json => alb-ingress-iam-policy.json | 0 iam_policy.json | 241 +++++++ kubernetes/alb-ingress-controller.yaml | 25 + kubernetes/crds.yaml | 590 ++++++++++++++++++ kubernetes/deployment.yml | 51 +- kubernetes/ingress.yaml | 21 + kubernetes/rbac-role.yaml | 53 ++ kubernetes/service.yaml | 15 + 9 files changed, 992 insertions(+), 7 deletions(-) rename kubernetes/alb-ingress-iam-policy.json => alb-ingress-iam-policy.json (100%) create mode 100644 iam_policy.json create mode 100644 kubernetes/alb-ingress-controller.yaml create mode 100644 kubernetes/crds.yaml create mode 100644 kubernetes/ingress.yaml create mode 100644 kubernetes/rbac-role.yaml create mode 100644 kubernetes/service.yaml diff --git a/README.md b/README.md index 55d8f75..4042cc9 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ - https://dev.to/asizikov/using-github-container-registry-with-kubernetes-38fb ghcr.io kubernetes - https://aws.amazon.com/blogs/containers/using-alb-ingress-controller-with-amazon-eks-on-fargate/ fargarte exose services +- https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html alb imp +- https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html eks ingress imp + ## TODOS - Golang API diff --git a/kubernetes/alb-ingress-iam-policy.json b/alb-ingress-iam-policy.json similarity index 100% rename from kubernetes/alb-ingress-iam-policy.json rename to alb-ingress-iam-policy.json diff --git a/iam_policy.json b/iam_policy.json new file mode 100644 index 0000000..7944f2a --- /dev/null +++ b/iam_policy.json @@ -0,0 +1,241 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:CreateServiceLinkedRole" + ], + "Resource": "*", + "Condition": { + "StringEquals": { + "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInternetGateways", + "ec2:DescribeVpcs", + "ec2:DescribeVpcPeeringConnections", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:DescribeInstances", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeTags", + "ec2:GetCoipPoolUsage", + "ec2:DescribeCoipPools", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTags" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "cognito-idp:DescribeUserPoolClient", + "acm:ListCertificates", + "acm:DescribeCertificate", + "iam:ListServerCertificates", + "iam:GetServerCertificate", + "waf-regional:GetWebACL", + "waf-regional:GetWebACLForResource", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL", + "shield:GetSubscriptionState", + "shield:DescribeProtection", + "shield:CreateProtection", + "shield:DeleteProtection" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateSecurityGroup" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateTags" + ], + "Resource": "arn:aws:ec2:*:*:security-group/*", + "Condition": { + "StringEquals": { + "ec2:CreateAction": "CreateSecurityGroup" + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:CreateTags", + "ec2:DeleteTags" + ], + "Resource": "arn:aws:ec2:*:*:security-group/*", + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:DeleteSecurityGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateTargetGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteRule" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + ], + "Condition": { + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:DeleteTargetGroup" + ], + "Resource": "*", + "Condition": { + "Null": { + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + ], + "Condition": { + "StringEquals": { + "elasticloadbalancing:CreateAction": [ + "CreateTargetGroup", + "CreateLoadBalancer" + ] + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets" + ], + "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:SetWebAcl", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:ModifyRule" + ], + "Resource": "*" + } + ] +} diff --git a/kubernetes/alb-ingress-controller.yaml b/kubernetes/alb-ingress-controller.yaml new file mode 100644 index 0000000..b16997e --- /dev/null +++ b/kubernetes/alb-ingress-controller.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: alb-ingress-controller + name: alb-ingress-controller + namespace: kube-system +spec: + selector: + matchLabels: + app.kubernetes.io/name: alb-ingress-controller + template: + metadata: + labels: + app.kubernetes.io/name: alb-ingress-controller + spec: + containers: + - name: alb-ingress-controller + args: + - --ingress-class=alb + - --cluster-name=eks-cluster + - --aws-vpc-id=vpc-0f5006f14bed22eb2 + - --aws-region=ap-south-1 + image: docker.io/amazon/aws-alb-ingress-controller:v1.1.6 + serviceAccountName: alb-ingress-controller diff --git a/kubernetes/crds.yaml b/kubernetes/crds.yaml new file mode 100644 index 0000000..78c2266 --- /dev/null +++ b/kubernetes/crds.yaml @@ -0,0 +1,590 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: ingressclassparams.elbv2.k8s.aws +spec: + group: elbv2.k8s.aws + names: + kind: IngressClassParams + listKind: IngressClassParamsList + plural: ingressclassparams + singular: ingressclassparams + scope: Cluster + versions: + - additionalPrinterColumns: + - description: The Ingress Group name + jsonPath: .spec.group.name + name: GROUP-NAME + type: string + - description: The AWS Load Balancer scheme + jsonPath: .spec.scheme + name: SCHEME + type: string + - description: The AWS Load Balancer ipAddressType + jsonPath: .spec.ipAddressType + name: IP-ADDRESS-TYPE + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: IngressClassParams is the Schema for the IngressClassParams API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: IngressClassParamsSpec defines the desired state of IngressClassParams + properties: + group: + description: Group defines the IngressGroup for all Ingresses that + belong to IngressClass with this IngressClassParams. + properties: + name: + description: Name is the name of IngressGroup. + type: string + required: + - name + type: object + inboundCIDRs: + description: InboundCIDRs specifies the CIDRs that are allowed to + access the Ingresses that belong to IngressClass with this IngressClassParams. + items: + type: string + type: array + ipAddressType: + description: IPAddressType defines the ip address type for all Ingresses + that belong to IngressClass with this IngressClassParams. + enum: + - ipv4 + - dualstack + type: string + loadBalancerAttributes: + description: LoadBalancerAttributes define the custom attributes to + LoadBalancers for all Ingress that that belong to IngressClass with + this IngressClassParams. + items: + description: Attributes defines custom attributes on resources. + properties: + key: + description: The key of the attribute. + type: string + value: + description: The value of the attribute. + type: string + required: + - key + - value + type: object + type: array + namespaceSelector: + description: NamespaceSelector restrict the namespaces of Ingresses + that are allowed to specify the IngressClass with this IngressClassParams. + * if absent or present but empty, it selects all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + scheme: + description: Scheme defines the scheme for all Ingresses that belong + to IngressClass with this IngressClassParams. + enum: + - internal + - internet-facing + type: string + sslPolicy: + description: SSLPolicy specifies the SSL Policy for all Ingresses + that belong to IngressClass with this IngressClassParams. + type: string + subnets: + description: Subnets defines the subnets for all Ingresses that belong + to IngressClass with this IngressClassParams. + properties: + ids: + description: IDs specify the resource IDs of subnets. Exactly + one of this or `tags` must be specified. + items: + description: SubnetID specifies a subnet ID. + pattern: subnet-[0-9a-f]+ + type: string + minItems: 1 + type: array + tags: + additionalProperties: + items: + type: string + type: array + description: Tags specifies subnets in the load balancer's VPC + where each tag specified in the map key contains one of the + values in the corresponding value list. Exactly one of this + or `ids` must be specified. + type: object + type: object + tags: + description: Tags defines list of Tags on AWS resources provisioned + for Ingresses that belong to IngressClass with this IngressClassParams. + items: + description: Tag defines a AWS Tag on resources. + properties: + key: + description: The key of the tag. + type: string + value: + description: The value of the tag. + type: string + required: + - key + - value + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: targetgroupbindings.elbv2.k8s.aws +spec: + group: elbv2.k8s.aws + names: + kind: TargetGroupBinding + listKind: TargetGroupBindingList + plural: targetgroupbindings + singular: targetgroupbinding + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Kubernetes Service's name + jsonPath: .spec.serviceRef.name + name: SERVICE-NAME + type: string + - description: The Kubernetes Service's port + jsonPath: .spec.serviceRef.port + name: SERVICE-PORT + type: string + - description: The AWS TargetGroup's TargetType + jsonPath: .spec.targetType + name: TARGET-TYPE + type: string + - description: The AWS TargetGroup's Amazon Resource Name + jsonPath: .spec.targetGroupARN + name: ARN + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: TargetGroupBinding is the Schema for the TargetGroupBinding API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TargetGroupBindingSpec defines the desired state of TargetGroupBinding + properties: + networking: + description: networking provides the networking setup for ELBV2 LoadBalancer + to access targets in TargetGroup. + properties: + ingress: + description: List of ingress rules to allow ELBV2 LoadBalancer + to access targets in TargetGroup. + items: + properties: + from: + description: List of peers which should be able to access + the targets in TargetGroup. At least one NetworkingPeer + should be specified. + items: + description: NetworkingPeer defines the source/destination + peer for networking rules. + properties: + ipBlock: + description: IPBlock defines an IPBlock peer. If specified, + none of the other fields can be set. + properties: + cidr: + description: CIDR is the network CIDR. Both IPV4 + or IPV6 CIDR are accepted. + type: string + required: + - cidr + type: object + securityGroup: + description: SecurityGroup defines a SecurityGroup + peer. If specified, none of the other fields can + be set. + properties: + groupID: + description: GroupID is the EC2 SecurityGroupID. + type: string + required: + - groupID + type: object + type: object + type: array + ports: + description: List of ports which should be made accessible + on the targets in TargetGroup. If ports is empty or unspecified, + it defaults to all ports with TCP. + items: + properties: + port: + anyOf: + - type: integer + - type: string + description: The port which traffic must match. When + NodePort endpoints(instance TargetType) is used, + this must be a numerical port. When Port endpoints(ip + TargetType) is used, this can be either numerical + or named port on pods. if port is unspecified, it + defaults to all ports. + x-kubernetes-int-or-string: true + protocol: + description: The protocol which traffic must match. + If protocol is unspecified, it defaults to TCP. + enum: + - TCP + - UDP + type: string + type: object + type: array + required: + - from + - ports + type: object + type: array + type: object + serviceRef: + description: serviceRef is a reference to a Kubernetes Service and + ServicePort. + properties: + name: + description: Name is the name of the Service. + type: string + port: + anyOf: + - type: integer + - type: string + description: Port is the port of the ServicePort. + x-kubernetes-int-or-string: true + required: + - name + - port + type: object + targetGroupARN: + description: targetGroupARN is the Amazon Resource Name (ARN) for + the TargetGroup. + type: string + targetType: + description: targetType is the TargetType of TargetGroup. If unspecified, + it will be automatically inferred. + enum: + - instance + - ip + type: string + required: + - serviceRef + - targetGroupARN + type: object + status: + description: TargetGroupBindingStatus defines the observed state of TargetGroupBinding + properties: + observedGeneration: + description: The generation observed by the TargetGroupBinding controller. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The Kubernetes Service's name + jsonPath: .spec.serviceRef.name + name: SERVICE-NAME + type: string + - description: The Kubernetes Service's port + jsonPath: .spec.serviceRef.port + name: SERVICE-PORT + type: string + - description: The AWS TargetGroup's TargetType + jsonPath: .spec.targetType + name: TARGET-TYPE + type: string + - description: The AWS TargetGroup's Amazon Resource Name + jsonPath: .spec.targetGroupARN + name: ARN + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: TargetGroupBinding is the Schema for the TargetGroupBinding API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TargetGroupBindingSpec defines the desired state of TargetGroupBinding + properties: + ipAddressType: + description: ipAddressType specifies whether the target group is of + type IPv4 or IPv6. If unspecified, it will be automatically inferred. + enum: + - ipv4 + - ipv6 + type: string + networking: + description: networking defines the networking rules to allow ELBV2 + LoadBalancer to access targets in TargetGroup. + properties: + ingress: + description: List of ingress rules to allow ELBV2 LoadBalancer + to access targets in TargetGroup. + items: + description: NetworkingIngressRule defines a particular set + of traffic that is allowed to access TargetGroup's targets. + properties: + from: + description: List of peers which should be able to access + the targets in TargetGroup. At least one NetworkingPeer + should be specified. + items: + description: NetworkingPeer defines the source/destination + peer for networking rules. + properties: + ipBlock: + description: IPBlock defines an IPBlock peer. If specified, + none of the other fields can be set. + properties: + cidr: + description: CIDR is the network CIDR. Both IPV4 + or IPV6 CIDR are accepted. + type: string + required: + - cidr + type: object + securityGroup: + description: SecurityGroup defines a SecurityGroup + peer. If specified, none of the other fields can + be set. + properties: + groupID: + description: GroupID is the EC2 SecurityGroupID. + type: string + required: + - groupID + type: object + type: object + type: array + ports: + description: List of ports which should be made accessible + on the targets in TargetGroup. If ports is empty or unspecified, + it defaults to all ports with TCP. + items: + description: NetworkingPort defines the port and protocol + for networking rules. + properties: + port: + anyOf: + - type: integer + - type: string + description: The port which traffic must match. When + NodePort endpoints(instance TargetType) is used, + this must be a numerical port. When Port endpoints(ip + TargetType) is used, this can be either numerical + or named port on pods. if port is unspecified, it + defaults to all ports. + x-kubernetes-int-or-string: true + protocol: + description: The protocol which traffic must match. + If protocol is unspecified, it defaults to TCP. + enum: + - TCP + - UDP + type: string + type: object + type: array + required: + - from + - ports + type: object + type: array + type: object + nodeSelector: + description: node selector for instance type target groups to only + register certain nodes + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + serviceRef: + description: serviceRef is a reference to a Kubernetes Service and + ServicePort. + properties: + name: + description: Name is the name of the Service. + type: string + port: + anyOf: + - type: integer + - type: string + description: Port is the port of the ServicePort. + x-kubernetes-int-or-string: true + required: + - name + - port + type: object + targetGroupARN: + description: targetGroupARN is the Amazon Resource Name (ARN) for + the TargetGroup. + minLength: 1 + type: string + targetType: + description: targetType is the TargetType of TargetGroup. If unspecified, + it will be automatically inferred. + enum: + - instance + - ip + type: string + required: + - serviceRef + - targetGroupARN + type: object + status: + description: TargetGroupBindingStatus defines the observed state of TargetGroupBinding + properties: + observedGeneration: + description: The generation observed by the TargetGroupBinding controller. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/kubernetes/deployment.yml b/kubernetes/deployment.yml index a86b04e..7c61548 100644 --- a/kubernetes/deployment.yml +++ b/kubernetes/deployment.yml @@ -4,7 +4,7 @@ kind: Deployment # Type of Kubernetes resource metadata: name: go-todo-api # Name of the Kubernetes resource spec: - replicas: 3 # Number of pods to run at any given time + replicas: 2 # Number of pods to run at any given time selector: matchLabels: app: go-todo-api # This deployment applies to any Pods matching the specified label @@ -36,18 +36,55 @@ spec: scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 1 -# Not for AWS Fargate --- apiVersion: v1 kind: Service metadata: - name: go-todo-api-loadbalancer + name: golang-todo-api-service spec: + ports: + - port: 8080 + targetPort: 8080 + # protocol: TCP type: LoadBalancer selector: app: go-todo-api - ports: - - protocol: TCP - port: 80 - targetPort: 8080 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: golang-todo-api-ingress + annotations: + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/target-type: ip + # alb.ingress.kubernetes.io/group.name: kube-alb-group #Use this to share ALB among multiple ingresses. #CostEffective + # alb.ingress.kubernetes.io/load-balancer-name: kube-alb # give ALB a meaningfull name otherwise a random name is assigned by AWS. + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:eu-west-1:XXXX:certificate/YYYY" # Get it by $ aws acm list-certificates + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' + alb.ingress.kubernetes.io/ssl-redirect: '443' +spec: + ingressClassName: alb + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: golang-todo-api-service + port: + number: 8080 +--- +apiVersion: autoscaling/v1 +kind: HorizontalPodAutoscaler +metadata: + name: php-apache +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: go-todo-api + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 60 \ No newline at end of file diff --git a/kubernetes/ingress.yaml b/kubernetes/ingress.yaml new file mode 100644 index 0000000..87a7d19 --- /dev/null +++ b/kubernetes/ingress.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: "go-todo-api-ingress" + namespace: "default" + annotations: + kubernetes.io/ingress.class: alb + alb.ingress.kubernetes.io/scheme: internet-facing + labels: + app: go-todo-api-ingress +spec: + rules: + - http: + paths: + - path: /* + pathType: Prefix + backend: + service: + name: "go-todo-api-service" + port: + number: 80 diff --git a/kubernetes/rbac-role.yaml b/kubernetes/rbac-role.yaml new file mode 100644 index 0000000..38906f6 --- /dev/null +++ b/kubernetes/rbac-role.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: alb-ingress-controller + name: alb-ingress-controller +rules: + - apiGroups: + - "" + - extensions + resources: + - configmaps + - endpoints + - events + - ingresses + - ingresses/status + - services + verbs: + - create + - get + - list + - update + - watch + - patch + - apiGroups: + - "" + - extensions + resources: + - nodes + - pods + - secrets + - services + - namespaces + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: alb-ingress-controller + name: alb-ingress-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: alb-ingress-controller +subjects: + - kind: ServiceAccount + name: alb-ingress-controller + namespace: kube-system diff --git a/kubernetes/service.yaml b/kubernetes/service.yaml new file mode 100644 index 0000000..245cc6b --- /dev/null +++ b/kubernetes/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + alb.ingress.kubernetes.io/target-type: ip + name: "go-todo-api-service" + namespace: "default" +spec: + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + type: NodePort + selector: + app: "go-todo-api" From 8a7bf9105584fcc4aa246796933b4f4f73a62c39 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Sat, 11 Nov 2023 02:26:23 +0530 Subject: [PATCH 03/22] cleanup --- alb-ingress-iam-policy.json | 140 ------ kubernetes/alb-ingress-controller.yaml | 25 -- kubernetes/crds.yaml | 590 ------------------------- kubernetes/deployment.yml | 89 ++-- kubernetes/docker-image-secret.yaml | 9 - kubernetes/ingress.yaml | 21 - kubernetes/rbac-role.yaml | 53 --- kubernetes/service.yaml | 15 - 8 files changed, 50 insertions(+), 892 deletions(-) delete mode 100644 alb-ingress-iam-policy.json delete mode 100644 kubernetes/alb-ingress-controller.yaml delete mode 100644 kubernetes/crds.yaml delete mode 100644 kubernetes/docker-image-secret.yaml delete mode 100644 kubernetes/ingress.yaml delete mode 100644 kubernetes/rbac-role.yaml delete mode 100644 kubernetes/service.yaml diff --git a/alb-ingress-iam-policy.json b/alb-ingress-iam-policy.json deleted file mode 100644 index b5b6bf0..0000000 --- a/alb-ingress-iam-policy.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "acm:DescribeCertificate", - "acm:ListCertificates", - "acm:GetCertificate" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AuthorizeSecurityGroupIngress", - "ec2:CreateSecurityGroup", - "ec2:CreateTags", - "ec2:DeleteTags", - "ec2:DeleteSecurityGroup", - "ec2:DescribeAccountAttributes", - "ec2:DescribeAddresses", - "ec2:DescribeInstances", - "ec2:DescribeInstanceStatus", - "ec2:DescribeInternetGateways", - "ec2:DescribeNetworkInterfaces", - "ec2:DescribeSecurityGroups", - "ec2:DescribeSubnets", - "ec2:DescribeTags", - "ec2:DescribeVpcs", - "ec2:ModifyInstanceAttribute", - "ec2:ModifyNetworkInterfaceAttribute", - "ec2:RevokeSecurityGroupIngress" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "elasticloadbalancing:AddListenerCertificates", - "elasticloadbalancing:AddTags", - "elasticloadbalancing:CreateListener", - "elasticloadbalancing:CreateLoadBalancer", - "elasticloadbalancing:CreateRule", - "elasticloadbalancing:CreateTargetGroup", - "elasticloadbalancing:DeleteListener", - "elasticloadbalancing:DeleteLoadBalancer", - "elasticloadbalancing:DeleteRule", - "elasticloadbalancing:DeleteTargetGroup", - "elasticloadbalancing:DeregisterTargets", - "elasticloadbalancing:DescribeListenerCertificates", - "elasticloadbalancing:DescribeListeners", - "elasticloadbalancing:DescribeLoadBalancers", - "elasticloadbalancing:DescribeLoadBalancerAttributes", - "elasticloadbalancing:DescribeRules", - "elasticloadbalancing:DescribeSSLPolicies", - "elasticloadbalancing:DescribeTags", - "elasticloadbalancing:DescribeTargetGroups", - "elasticloadbalancing:DescribeTargetGroupAttributes", - "elasticloadbalancing:DescribeTargetHealth", - "elasticloadbalancing:ModifyListener", - "elasticloadbalancing:ModifyLoadBalancerAttributes", - "elasticloadbalancing:ModifyRule", - "elasticloadbalancing:ModifyTargetGroup", - "elasticloadbalancing:ModifyTargetGroupAttributes", - "elasticloadbalancing:RegisterTargets", - "elasticloadbalancing:RemoveListenerCertificates", - "elasticloadbalancing:RemoveTags", - "elasticloadbalancing:SetIpAddressType", - "elasticloadbalancing:SetSecurityGroups", - "elasticloadbalancing:SetSubnets", - "elasticloadbalancing:SetWebAcl" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "iam:CreateServiceLinkedRole", - "iam:GetServerCertificate", - "iam:ListServerCertificates" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "cognito-idp:DescribeUserPoolClient" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "waf-regional:GetWebACLForResource", - "waf-regional:GetWebACL", - "waf-regional:AssociateWebACL", - "waf-regional:DisassociateWebACL" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "tag:GetResources", - "tag:TagResources" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "waf:GetWebACL" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "wafv2:GetWebACL", - "wafv2:GetWebACLForResource", - "wafv2:AssociateWebACL", - "wafv2:DisassociateWebACL" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "shield:DescribeProtection", - "shield:GetSubscriptionState", - "shield:DeleteProtection", - "shield:CreateProtection", - "shield:DescribeSubscription", - "shield:ListProtections" - ], - "Resource": "*" - } - ] -} diff --git a/kubernetes/alb-ingress-controller.yaml b/kubernetes/alb-ingress-controller.yaml deleted file mode 100644 index b16997e..0000000 --- a/kubernetes/alb-ingress-controller.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/name: alb-ingress-controller - name: alb-ingress-controller - namespace: kube-system -spec: - selector: - matchLabels: - app.kubernetes.io/name: alb-ingress-controller - template: - metadata: - labels: - app.kubernetes.io/name: alb-ingress-controller - spec: - containers: - - name: alb-ingress-controller - args: - - --ingress-class=alb - - --cluster-name=eks-cluster - - --aws-vpc-id=vpc-0f5006f14bed22eb2 - - --aws-region=ap-south-1 - image: docker.io/amazon/aws-alb-ingress-controller:v1.1.6 - serviceAccountName: alb-ingress-controller diff --git a/kubernetes/crds.yaml b/kubernetes/crds.yaml deleted file mode 100644 index 78c2266..0000000 --- a/kubernetes/crds.yaml +++ /dev/null @@ -1,590 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null - name: ingressclassparams.elbv2.k8s.aws -spec: - group: elbv2.k8s.aws - names: - kind: IngressClassParams - listKind: IngressClassParamsList - plural: ingressclassparams - singular: ingressclassparams - scope: Cluster - versions: - - additionalPrinterColumns: - - description: The Ingress Group name - jsonPath: .spec.group.name - name: GROUP-NAME - type: string - - description: The AWS Load Balancer scheme - jsonPath: .spec.scheme - name: SCHEME - type: string - - description: The AWS Load Balancer ipAddressType - jsonPath: .spec.ipAddressType - name: IP-ADDRESS-TYPE - type: string - - jsonPath: .metadata.creationTimestamp - name: AGE - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: IngressClassParams is the Schema for the IngressClassParams API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: IngressClassParamsSpec defines the desired state of IngressClassParams - properties: - group: - description: Group defines the IngressGroup for all Ingresses that - belong to IngressClass with this IngressClassParams. - properties: - name: - description: Name is the name of IngressGroup. - type: string - required: - - name - type: object - inboundCIDRs: - description: InboundCIDRs specifies the CIDRs that are allowed to - access the Ingresses that belong to IngressClass with this IngressClassParams. - items: - type: string - type: array - ipAddressType: - description: IPAddressType defines the ip address type for all Ingresses - that belong to IngressClass with this IngressClassParams. - enum: - - ipv4 - - dualstack - type: string - loadBalancerAttributes: - description: LoadBalancerAttributes define the custom attributes to - LoadBalancers for all Ingress that that belong to IngressClass with - this IngressClassParams. - items: - description: Attributes defines custom attributes on resources. - properties: - key: - description: The key of the attribute. - type: string - value: - description: The value of the attribute. - type: string - required: - - key - - value - type: object - type: array - namespaceSelector: - description: NamespaceSelector restrict the namespaces of Ingresses - that are allowed to specify the IngressClass with this IngressClassParams. - * if absent or present but empty, it selects all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - scheme: - description: Scheme defines the scheme for all Ingresses that belong - to IngressClass with this IngressClassParams. - enum: - - internal - - internet-facing - type: string - sslPolicy: - description: SSLPolicy specifies the SSL Policy for all Ingresses - that belong to IngressClass with this IngressClassParams. - type: string - subnets: - description: Subnets defines the subnets for all Ingresses that belong - to IngressClass with this IngressClassParams. - properties: - ids: - description: IDs specify the resource IDs of subnets. Exactly - one of this or `tags` must be specified. - items: - description: SubnetID specifies a subnet ID. - pattern: subnet-[0-9a-f]+ - type: string - minItems: 1 - type: array - tags: - additionalProperties: - items: - type: string - type: array - description: Tags specifies subnets in the load balancer's VPC - where each tag specified in the map key contains one of the - values in the corresponding value list. Exactly one of this - or `ids` must be specified. - type: object - type: object - tags: - description: Tags defines list of Tags on AWS resources provisioned - for Ingresses that belong to IngressClass with this IngressClassParams. - items: - description: Tag defines a AWS Tag on resources. - properties: - key: - description: The key of the tag. - type: string - value: - description: The value of the tag. - type: string - required: - - key - - value - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.11.1 - creationTimestamp: null - name: targetgroupbindings.elbv2.k8s.aws -spec: - group: elbv2.k8s.aws - names: - kind: TargetGroupBinding - listKind: TargetGroupBindingList - plural: targetgroupbindings - singular: targetgroupbinding - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: The Kubernetes Service's name - jsonPath: .spec.serviceRef.name - name: SERVICE-NAME - type: string - - description: The Kubernetes Service's port - jsonPath: .spec.serviceRef.port - name: SERVICE-PORT - type: string - - description: The AWS TargetGroup's TargetType - jsonPath: .spec.targetType - name: TARGET-TYPE - type: string - - description: The AWS TargetGroup's Amazon Resource Name - jsonPath: .spec.targetGroupARN - name: ARN - priority: 1 - type: string - - jsonPath: .metadata.creationTimestamp - name: AGE - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: TargetGroupBinding is the Schema for the TargetGroupBinding API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: TargetGroupBindingSpec defines the desired state of TargetGroupBinding - properties: - networking: - description: networking provides the networking setup for ELBV2 LoadBalancer - to access targets in TargetGroup. - properties: - ingress: - description: List of ingress rules to allow ELBV2 LoadBalancer - to access targets in TargetGroup. - items: - properties: - from: - description: List of peers which should be able to access - the targets in TargetGroup. At least one NetworkingPeer - should be specified. - items: - description: NetworkingPeer defines the source/destination - peer for networking rules. - properties: - ipBlock: - description: IPBlock defines an IPBlock peer. If specified, - none of the other fields can be set. - properties: - cidr: - description: CIDR is the network CIDR. Both IPV4 - or IPV6 CIDR are accepted. - type: string - required: - - cidr - type: object - securityGroup: - description: SecurityGroup defines a SecurityGroup - peer. If specified, none of the other fields can - be set. - properties: - groupID: - description: GroupID is the EC2 SecurityGroupID. - type: string - required: - - groupID - type: object - type: object - type: array - ports: - description: List of ports which should be made accessible - on the targets in TargetGroup. If ports is empty or unspecified, - it defaults to all ports with TCP. - items: - properties: - port: - anyOf: - - type: integer - - type: string - description: The port which traffic must match. When - NodePort endpoints(instance TargetType) is used, - this must be a numerical port. When Port endpoints(ip - TargetType) is used, this can be either numerical - or named port on pods. if port is unspecified, it - defaults to all ports. - x-kubernetes-int-or-string: true - protocol: - description: The protocol which traffic must match. - If protocol is unspecified, it defaults to TCP. - enum: - - TCP - - UDP - type: string - type: object - type: array - required: - - from - - ports - type: object - type: array - type: object - serviceRef: - description: serviceRef is a reference to a Kubernetes Service and - ServicePort. - properties: - name: - description: Name is the name of the Service. - type: string - port: - anyOf: - - type: integer - - type: string - description: Port is the port of the ServicePort. - x-kubernetes-int-or-string: true - required: - - name - - port - type: object - targetGroupARN: - description: targetGroupARN is the Amazon Resource Name (ARN) for - the TargetGroup. - type: string - targetType: - description: targetType is the TargetType of TargetGroup. If unspecified, - it will be automatically inferred. - enum: - - instance - - ip - type: string - required: - - serviceRef - - targetGroupARN - type: object - status: - description: TargetGroupBindingStatus defines the observed state of TargetGroupBinding - properties: - observedGeneration: - description: The generation observed by the TargetGroupBinding controller. - format: int64 - type: integer - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - description: The Kubernetes Service's name - jsonPath: .spec.serviceRef.name - name: SERVICE-NAME - type: string - - description: The Kubernetes Service's port - jsonPath: .spec.serviceRef.port - name: SERVICE-PORT - type: string - - description: The AWS TargetGroup's TargetType - jsonPath: .spec.targetType - name: TARGET-TYPE - type: string - - description: The AWS TargetGroup's Amazon Resource Name - jsonPath: .spec.targetGroupARN - name: ARN - priority: 1 - type: string - - jsonPath: .metadata.creationTimestamp - name: AGE - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: TargetGroupBinding is the Schema for the TargetGroupBinding API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: TargetGroupBindingSpec defines the desired state of TargetGroupBinding - properties: - ipAddressType: - description: ipAddressType specifies whether the target group is of - type IPv4 or IPv6. If unspecified, it will be automatically inferred. - enum: - - ipv4 - - ipv6 - type: string - networking: - description: networking defines the networking rules to allow ELBV2 - LoadBalancer to access targets in TargetGroup. - properties: - ingress: - description: List of ingress rules to allow ELBV2 LoadBalancer - to access targets in TargetGroup. - items: - description: NetworkingIngressRule defines a particular set - of traffic that is allowed to access TargetGroup's targets. - properties: - from: - description: List of peers which should be able to access - the targets in TargetGroup. At least one NetworkingPeer - should be specified. - items: - description: NetworkingPeer defines the source/destination - peer for networking rules. - properties: - ipBlock: - description: IPBlock defines an IPBlock peer. If specified, - none of the other fields can be set. - properties: - cidr: - description: CIDR is the network CIDR. Both IPV4 - or IPV6 CIDR are accepted. - type: string - required: - - cidr - type: object - securityGroup: - description: SecurityGroup defines a SecurityGroup - peer. If specified, none of the other fields can - be set. - properties: - groupID: - description: GroupID is the EC2 SecurityGroupID. - type: string - required: - - groupID - type: object - type: object - type: array - ports: - description: List of ports which should be made accessible - on the targets in TargetGroup. If ports is empty or unspecified, - it defaults to all ports with TCP. - items: - description: NetworkingPort defines the port and protocol - for networking rules. - properties: - port: - anyOf: - - type: integer - - type: string - description: The port which traffic must match. When - NodePort endpoints(instance TargetType) is used, - this must be a numerical port. When Port endpoints(ip - TargetType) is used, this can be either numerical - or named port on pods. if port is unspecified, it - defaults to all ports. - x-kubernetes-int-or-string: true - protocol: - description: The protocol which traffic must match. - If protocol is unspecified, it defaults to TCP. - enum: - - TCP - - UDP - type: string - type: object - type: array - required: - - from - - ports - type: object - type: array - type: object - nodeSelector: - description: node selector for instance type target groups to only - register certain nodes - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - serviceRef: - description: serviceRef is a reference to a Kubernetes Service and - ServicePort. - properties: - name: - description: Name is the name of the Service. - type: string - port: - anyOf: - - type: integer - - type: string - description: Port is the port of the ServicePort. - x-kubernetes-int-or-string: true - required: - - name - - port - type: object - targetGroupARN: - description: targetGroupARN is the Amazon Resource Name (ARN) for - the TargetGroup. - minLength: 1 - type: string - targetType: - description: targetType is the TargetType of TargetGroup. If unspecified, - it will be automatically inferred. - enum: - - instance - - ip - type: string - required: - - serviceRef - - targetGroupARN - type: object - status: - description: TargetGroupBindingStatus defines the observed state of TargetGroupBinding - properties: - observedGeneration: - description: The generation observed by the TargetGroupBinding controller. - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/kubernetes/deployment.yml b/kubernetes/deployment.yml index 7c61548..6c2d3ec 100644 --- a/kubernetes/deployment.yml +++ b/kubernetes/deployment.yml @@ -1,41 +1,41 @@ --- apiVersion: apps/v1 -kind: Deployment # Type of Kubernetes resource +kind: Deployment # Type of Kubernetes resource metadata: - name: go-todo-api # Name of the Kubernetes resource + name: go-todo-api # Name of the Kubernetes resource spec: - replicas: 2 # Number of pods to run at any given time + replicas: 2 # Number of pods to run at any given time selector: matchLabels: - app: go-todo-api # This deployment applies to any Pods matching the specified label - template: # This deployment will create a set of pods using the configurations in this template + app: go-todo-api # This deployment applies to any Pods matching the specified label + template: # This deployment will create a set of pods using the configurations in this template metadata: - labels: # The labels that will be applied to all of the pods in this deployment - app: go-todo-api - spec: # Spec for the container which will run in the Pod + labels: # The labels that will be applied to all of the pods in this deployment + app: go-todo-api + spec: # Spec for the container which will run in the Pod imagePullSecrets: - - name: dockerconfigjson-github-com + - name: dockerconfigjson-github-com containers: - - name: go-todo-api - image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest - imagePullPolicy: Always # IfNotPresent - ports: - - containerPort: 8080 # Should match the port number that the Go application listens on - livenessProbe: # To check the health of the Pod - httpGet: - path: /health - port: 8080 - scheme: HTTP - initialDelaySeconds: 5 - periodSeconds: 15 - timeoutSeconds: 5 - readinessProbe: # To check if the Pod is ready to serve traffic or not - httpGet: - path: /readiness - port: 8080 - scheme: HTTP - initialDelaySeconds: 5 - timeoutSeconds: 1 + - name: go-todo-api + image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest + imagePullPolicy: Always # IfNotPresent + ports: + - containerPort: 8080 # Should match the port number that the Go application listens on + livenessProbe: # To check the health of the Pod + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 15 + timeoutSeconds: 5 + readinessProbe: # To check if the Pod is ready to serve traffic or not + httpGet: + path: /readiness + port: 8080 + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 1 --- apiVersion: v1 kind: Service @@ -59,21 +59,32 @@ metadata: alb.ingress.kubernetes.io/target-type: ip # alb.ingress.kubernetes.io/group.name: kube-alb-group #Use this to share ALB among multiple ingresses. #CostEffective # alb.ingress.kubernetes.io/load-balancer-name: kube-alb # give ALB a meaningfull name otherwise a random name is assigned by AWS. - # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:eu-west-1:XXXX:certificate/YYYY" # Get it by $ aws acm list-certificates + # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:eu-west-1:XXXX:certificate/YYYY" # Get it by $ aws acm list-certificates alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' - alb.ingress.kubernetes.io/ssl-redirect: '443' + alb.ingress.kubernetes.io/ssl-redirect: "443" spec: ingressClassName: alb rules: - http: paths: - - path: / - pathType: Prefix - backend: - service: - name: golang-todo-api-service - port: - number: 8080 + - path: / + pathType: Prefix + backend: + service: + name: golang-todo-api-service + port: + number: 8080 + +--- +kind: Secret +type: kubernetes.io/dockerconfigjson +apiVersion: v1 +metadata: + name: dockerconfigjson-github-com + labels: + app: app-name +data: + .dockerconfigjson: eyAiYXV0aHMiOiB7ICJnaGNyLmlvIjogeyAiYXV0aCI6ImFHRnljMmh6YVc1bmFIWnBPbWRvY0Y5UU1FOHdZbXRXU0VwMVYzbHJObWRPVnpaQ1lWYzRRMFY2Y25sTFVXZ3hkRkp1UlVrPSIgfSB9IH0= --- apiVersion: autoscaling/v1 @@ -87,4 +98,4 @@ spec: name: go-todo-api minReplicas: 1 maxReplicas: 10 - targetCPUUtilizationPercentage: 60 \ No newline at end of file + targetCPUUtilizationPercentage: 60 diff --git a/kubernetes/docker-image-secret.yaml b/kubernetes/docker-image-secret.yaml deleted file mode 100644 index 6c8de9a..0000000 --- a/kubernetes/docker-image-secret.yaml +++ /dev/null @@ -1,9 +0,0 @@ -kind: Secret -type: kubernetes.io/dockerconfigjson -apiVersion: v1 -metadata: - name: dockerconfigjson-github-com - labels: - app: app-name -data: - .dockerconfigjson: eyAiYXV0aHMiOiB7ICJnaGNyLmlvIjogeyAiYXV0aCI6ImFHRnljMmh6YVc1bmFIWnBPbWRvY0Y5UU1FOHdZbXRXU0VwMVYzbHJObWRPVnpaQ1lWYzRRMFY2Y25sTFVXZ3hkRkp1UlVrPSIgfSB9IH0= diff --git a/kubernetes/ingress.yaml b/kubernetes/ingress.yaml deleted file mode 100644 index 87a7d19..0000000 --- a/kubernetes/ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: "go-todo-api-ingress" - namespace: "default" - annotations: - kubernetes.io/ingress.class: alb - alb.ingress.kubernetes.io/scheme: internet-facing - labels: - app: go-todo-api-ingress -spec: - rules: - - http: - paths: - - path: /* - pathType: Prefix - backend: - service: - name: "go-todo-api-service" - port: - number: 80 diff --git a/kubernetes/rbac-role.yaml b/kubernetes/rbac-role.yaml deleted file mode 100644 index 38906f6..0000000 --- a/kubernetes/rbac-role.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: alb-ingress-controller - name: alb-ingress-controller -rules: - - apiGroups: - - "" - - extensions - resources: - - configmaps - - endpoints - - events - - ingresses - - ingresses/status - - services - verbs: - - create - - get - - list - - update - - watch - - patch - - apiGroups: - - "" - - extensions - resources: - - nodes - - pods - - secrets - - services - - namespaces - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: alb-ingress-controller - name: alb-ingress-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: alb-ingress-controller -subjects: - - kind: ServiceAccount - name: alb-ingress-controller - namespace: kube-system diff --git a/kubernetes/service.yaml b/kubernetes/service.yaml deleted file mode 100644 index 245cc6b..0000000 --- a/kubernetes/service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - annotations: - alb.ingress.kubernetes.io/target-type: ip - name: "go-todo-api-service" - namespace: "default" -spec: - ports: - - port: 80 - targetPort: 8080 - protocol: TCP - type: NodePort - selector: - app: "go-todo-api" From 0ce9f2276453a88be776de2b0b0e96223b950db7 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Sat, 11 Nov 2023 02:27:07 +0530 Subject: [PATCH 04/22] Format --- kubernetes/deployment.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kubernetes/deployment.yml b/kubernetes/deployment.yml index 6c2d3ec..4ff81fb 100644 --- a/kubernetes/deployment.yml +++ b/kubernetes/deployment.yml @@ -36,6 +36,7 @@ spec: scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 1 + --- apiVersion: v1 kind: Service @@ -49,6 +50,7 @@ spec: type: LoadBalancer selector: app: go-todo-api + --- apiVersion: networking.k8s.io/v1 kind: Ingress From 06ddc929e1fd0e2f37bfaee849f49e71a715fbcd Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Sat, 11 Nov 2023 02:29:16 +0530 Subject: [PATCH 05/22] remove extra configs --- kubernetes/deployment.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kubernetes/deployment.yml b/kubernetes/deployment.yml index 4ff81fb..be5c5fb 100644 --- a/kubernetes/deployment.yml +++ b/kubernetes/deployment.yml @@ -59,11 +59,12 @@ metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip + # alb.ingress.kubernetes.io/group.name: kube-alb-group #Use this to share ALB among multiple ingresses. #CostEffective # alb.ingress.kubernetes.io/load-balancer-name: kube-alb # give ALB a meaningfull name otherwise a random name is assigned by AWS. # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:eu-west-1:XXXX:certificate/YYYY" # Get it by $ aws acm list-certificates - alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' - alb.ingress.kubernetes.io/ssl-redirect: "443" + # alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' + # alb.ingress.kubernetes.io/ssl-redirect: "443" spec: ingressClassName: alb rules: From e8a52b6f547bcefc0076aa12915b17c68117e05d Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 18:19:55 +0530 Subject: [PATCH 06/22] k8s files --- kubernetes/database.yml | 101 +++++++++++++++++ kubernetes/deployment.yml | 16 ++- kubernetes/matrics-server.yaml | 197 +++++++++++++++++++++++++++++++++ loadgenerator.yml | 25 +++++ 4 files changed, 334 insertions(+), 5 deletions(-) create mode 100644 kubernetes/database.yml create mode 100644 kubernetes/matrics-server.yaml create mode 100644 loadgenerator.yml diff --git a/kubernetes/database.yml b/kubernetes/database.yml new file mode 100644 index 0000000..9644aa4 --- /dev/null +++ b/kubernetes/database.yml @@ -0,0 +1,101 @@ +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: efs-pv +spec: + capacity: + storage: 5Gi + volumeMode: Filesystem + accessModes: + - ReadWriteMany + persistentVolumeReclaimPolicy: Retain + storageClassName: efs-sc + csi: + driver: efs.csi.aws.com + volumeHandle: fs-07cbaab02f39869e2 + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: efs-claim +spec: + accessModes: + - ReadWriteMany + storageClassName: efs-sc + resources: + requests: + storage: 5Gi + +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: efs-sc +provisioner: efs.csi.aws.com + +--- +apiVersion: v1 +kind: Secret +metadata: + name: postgres-secret +type: Opaque +stringData: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + +--- +apiVersion: apps/v1 +kind: StatefulSet # Type of the kubernetes resource +metadata: + name: postgres # Name of the statefulset + labels: # Labels applied to this statefulset + app: postgres +spec: + serviceName: postgres + selector: + matchLabels: # This statefulset applies to the Pods matching the specified labels + app: postgres + tier: postgres + replicas: 1 + template: # Template for the Pods in this statefulset + metadata: + labels: # Labels to be applied to the Pods in this statefulset + app: postgres + tier: postgres + spec: # The spec for the containers that will be run inside the Pods in this statefulset + containers: + - image: postgres:latest # The container image + name: postgres + imagePullPolicy: "IfNotPresent" + envFrom: # Get the environmental variables from a secret file whose name is "postgres-secret" + - secretRef: + name: postgres-secret + ports: + - containerPort: 5432 # The port that the container exposes + name: postgres + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: postgres-persistent-storage # This name should match the name specified in `volumes.name` + volumes: # A PersistentVolume is mounted as a volume to the Pod + - name: postgres-persistent-storage + persistentVolumeClaim: + claimName: efs-claim + +--- +apiVersion: v1 # API version +kind: Service # Type of kubernetes resource +metadata: + name: postgres # Name of the resource + labels: # Labels that will be applied to the resource + app: postgres +spec: + ports: + - name: db + port: 5432 + targetPort: 5432 # Exposing default port of 5432. + selector: # Selects any Pod with labels `app=fullstack-postgres,tier=postgres` + app: postgres + tier: postgres diff --git a/kubernetes/deployment.yml b/kubernetes/deployment.yml index be5c5fb..4929e76 100644 --- a/kubernetes/deployment.yml +++ b/kubernetes/deployment.yml @@ -4,7 +4,7 @@ kind: Deployment # Type of Kubernetes resource metadata: name: go-todo-api # Name of the Kubernetes resource spec: - replicas: 2 # Number of pods to run at any given time + replicas: 3 # Number of pods to run at any given time selector: matchLabels: app: go-todo-api # This deployment applies to any Pods matching the specified label @@ -18,9 +18,14 @@ spec: containers: - name: go-todo-api image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest - imagePullPolicy: Always # IfNotPresent + imagePullPolicy: IfNotPresent # Always ports: - containerPort: 8080 # Should match the port number that the Go application listens on + resources: + limits: + cpu: '500m' + requests: + cpu: '200m' livenessProbe: # To check the health of the Pod httpGet: path: /health @@ -93,12 +98,13 @@ data: apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: - name: php-apache + name: go-todo-api-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: go-todo-api - minReplicas: 1 + minReplicas: 2 maxReplicas: 10 - targetCPUUtilizationPercentage: 60 + targetCPUUtilizationPercentage: 30 + diff --git a/kubernetes/matrics-server.yaml b/kubernetes/matrics-server.yaml new file mode 100644 index 0000000..d84b7e2 --- /dev/null +++ b/kubernetes/matrics-server.yaml @@ -0,0 +1,197 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: system:aggregated-metrics-reader +rules: +- apiGroups: + - metrics.k8s.io + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +rules: +- apiGroups: + - "" + resources: + - nodes/metrics + verbs: + - get +- apiGroups: + - "" + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:metrics-server +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: https + selector: + k8s-app: metrics-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +spec: + selector: + matchLabels: + k8s-app: metrics-server + strategy: + rollingUpdate: + maxUnavailable: 0 + template: + metadata: + labels: + k8s-app: metrics-server + spec: + containers: + - args: + - --cert-dir=/tmp + - --secure-port=4443 + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --kubelet-insecure-tls + image: registry.k8s.io/metrics-server/metrics-server:v0.6.4 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 10 + name: metrics-server + ports: + - containerPort: 4443 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + volumeMounts: + - mountPath: /tmp + name: tmp-dir + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + serviceAccountName: metrics-server + volumes: + - emptyDir: {} + name: tmp-dir +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + labels: + k8s-app: metrics-server + name: v1beta1.metrics.k8s.io +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: metrics-server + namespace: kube-system + version: v1beta1 + versionPriority: 100 diff --git a/loadgenerator.yml b/loadgenerator.yml new file mode 100644 index 0000000..7d6cd30 --- /dev/null +++ b/loadgenerator.yml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: loadgenerator + labels: + app: loadgenerator +spec: + replicas: 3 + selector: + matchLabels: + app: loadgenerator + template: + metadata: + name: loadgenerator + labels: + app: loadgenerator + spec: + containers: + - name: loadgenerator + imagePullPolicy: IfNotPresent # Always + image: busybox + command: + - /bin/sh + - -c + - "while true; do wget -q -O- http://golang-todo-api-service:8080/todos; done" \ No newline at end of file From 4b1e8ff1cf0ef14845a2a4820d352925a9dfaf75 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 18:20:08 +0530 Subject: [PATCH 07/22] auto scale results --- README.md | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/README.md b/README.md index 4042cc9..4259dca 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ - https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html alb imp - https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html eks ingress imp +- https://artifacthub.io/packages/helm/metrics-server/metrics-server install Matrics server +- https://docs.aws.amazon.com/eks/latest/userguide/metrics-server.html matrics server +- https://levelup.gitconnected.com/how-to-deploy-a-multi-container-two-tier-go-application-in-eks-fargate-6266494f5bcf go and postgres eks ## TODOS @@ -51,3 +54,155 @@ echo $CR_PAT | docker login ghcr.io -u harshsinghvi --password-stdin docker buildx build --platform=linux/amd64 -t ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest . docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest + +``` + +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 2 19m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 19m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 19m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 20m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m + +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 1 21m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 27%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 25%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 27%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 1 24m +go-todo-api-hpa Deployment/go-todo-api 37%/30% 1 10 2 24m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 2 24m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 2 24m +go-todo-api-hpa Deployment/go-todo-api 37%/30% 1 10 2 25m +go-todo-api-hpa Deployment/go-todo-api 29%/30% 1 10 2 25m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 2 25m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 26m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 26m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 27m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 29m +go-todo-api-hpa Deployment/go-todo-api 67%/30% 1 10 2 29m +go-todo-api-hpa Deployment/go-todo-api 73%/30% 1 10 4 29m +go-todo-api-hpa Deployment/go-todo-api 75%/30% 1 10 5 29m +go-todo-api-hpa Deployment/go-todo-api 74%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 73%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 72%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 6%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 32m +go-todo-api-hpa Deployment/go-todo-api 28%/30% 1 10 5 32m +go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 5 32m +go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 7 32m +go-todo-api-hpa Deployment/go-todo-api 39%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 43%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 7%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 6%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 7%/30% 1 10 7 35m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 35m +go-todo-api-hpa Deployment/go-todo-api 32%/30% 1 10 7 35m +go-todo-api-hpa Deployment/go-todo-api 33%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 42%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 17%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 9%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 9%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 10%/30% 1 10 7 38m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 38m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 7 38m +go-todo-api-hpa Deployment/go-todo-api 31%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 44%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 45%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 34%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 7 40m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 7 40m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 40m +go-todo-api-hpa Deployment/go-todo-api 30%/30% 1 10 7 41m +go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 7 41m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 7 41m +go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 7 42m +go-todo-api-hpa Deployment/go-todo-api 32%/30% 1 10 7 42m +go-todo-api-hpa Deployment/go-todo-api 31%/30% 1 10 7 42m +go-todo-api-hpa Deployment/go-todo-api 29%/30% 1 10 7 43m +go-todo-api-hpa Deployment/go-todo-api 25%/30% 1 10 7 43m +go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 17%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 48m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 48m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 48m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 5 48m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 4 50m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 3 50m +go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 50m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 3 50m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 3 51m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 3 51m +go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 3 53m +go-todo-api-hpa Deployment/go-todo-api 0%/30% 1 10 3 53m +``` + +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-0f8e0a7152ce63763 \ + --security-groups $security_group_id + +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-0e2824fc49bdcd202 \ + --security-groups $security_group_id + +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-028474cfc7ca5c2c5 \ + --security-groups $security_group_id + +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-060db0728f89d0203 \ + --security-groups $security_group_id + +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-00782a5c917b7ae74 \ + --security-groups $security_group_id + +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-0a7fb187cb42744b1 \ + --security-groups $security_group_id From 911e87f99fef0b4517c65488a8e172eb5223f03d Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 18:20:21 +0530 Subject: [PATCH 08/22] API V2 with postgres --- database/database.go | 161 +++++++++++++++++++++++++++++++++++++++++++ db.sql | 2 +- go.mod | 12 ++++ go.sum | 120 ++++++++++++++++++++++++++++++++ main.go | 46 ++++++++----- models/todo.go | 13 ++++ 6 files changed, 337 insertions(+), 17 deletions(-) create mode 100644 database/database.go create mode 100644 models/todo.go diff --git a/database/database.go b/database/database.go new file mode 100644 index 0000000..df28c95 --- /dev/null +++ b/database/database.go @@ -0,0 +1,161 @@ +package database + +import ( + . "harshsinghvi/golang-postgres-kubernetes/models" + + "github.com/go-pg/pg/v9" + orm "github.com/go-pg/pg/v9/orm" + guuid "github.com/google/uuid" + "log" + "os" + + "github.com/gin-gonic/gin" + "net/http" + "time" +) + +var database_ready = false +var connection *pg.DB + +func IsDtabaseReady() bool { + return database_ready +} + +func GetDatabase() *pg.DB { + return connection +} + +func Connect() *pg.DB { + opts := &pg.Options{ + User: "postgres", + Password: "postgres", + Addr: "localhost:5432", + Database: "postgres", + } + connection = pg.Connect(opts) + if connection == nil { + log.Printf("Failed to connect") + os.Exit(100) + } + log.Printf("Connected to db") + return connection +} + +// Create User Table +func CreateTodoTable() error { + opts := &orm.CreateTableOptions{ + IfNotExists: true, + } + createError := connection.CreateTable(&Todo{}, opts) + if createError != nil { + log.Printf("Error while creating todo table, Reason: %v\n", createError) + return createError + } + log.Printf("Todo table created") + return nil +} + +func GetAllTodos(c *gin.Context) { + var todos []Todo + err := connection.Model(&todos).Select() + if err != nil { + log.Printf("Error while getting all todos, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "All Todos", + "data": todos, + }) +} + +func GetSingleTodo(c *gin.Context) { + todoId := c.Param("id") + todo := &Todo{ID: todoId} + err := connection.Select(todo) + if err != nil { + log.Printf("Error while getting a single todo, Reason: %v\n", err) + c.JSON(http.StatusNotFound, gin.H{ + "status": http.StatusNotFound, + "message": "Todo not found", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "Single Todo", + "data": todo, + }) +} + +func CreateTodo(c *gin.Context) { + var todo Todo + c.BindJSON(&todo) + + text := todo.Text + id := guuid.New().String() + + insertError := connection.Insert(&Todo{ + ID: id, + Text: text, + Completed: false, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + }) + + if insertError != nil { + log.Printf("Error while inserting new todo into db, Reason: %v\n", insertError) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } + + c.JSON(http.StatusCreated, gin.H{ + "status": http.StatusCreated, + "message": "Todo created Successfully", + }) +} + +func EditTodo(c *gin.Context) { + todoId := c.Param("id") + var todo Todo + c.BindJSON(&todo) + completed := todo.Completed + _, err := connection.Model(&Todo{}).Set("completed = ?", completed).Where("id = ?", todoId).Update() + if err != nil { + log.Printf("Error, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": 500, + "message": "Something went wrong", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": 200, + "message": "Todo Edited Successfully", + }) +} + +func DeleteTodo(c *gin.Context) { + todoId := c.Param("id") + todo := &Todo{ID: todoId} + err := connection.Delete(todo) + if err != nil { + log.Printf("Error while deleting a single todo, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "Todo deleted successfully", + }) +} diff --git a/db.sql b/db.sql index af3dd9f..a30d86a 100644 --- a/db.sql +++ b/db.sql @@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS todos ( complete BOOLEAN NOT NULL ); -SELECT id,text, complete FROM todos +SELECT id,text, complete FROM todos; UPDATE todos SET text='nae56', WHERE id=1; diff --git a/go.mod b/go.mod index 1e44f29..abc0809 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,24 @@ go 1.21.1 require ( github.com/gin-gonic/gin v1.9.1 + github.com/go-pg/pg/v9 v9.2.1 + github.com/google/uuid v1.4.0 github.com/lib/pq v1.10.9 ) require ( github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/codemodus/kace v0.5.1 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-pg/zerochecker v0.2.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/golang/protobuf v1.5.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect @@ -23,13 +29,19 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/segmentio/encoding v0.1.15 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + github.com/vmihailenco/bufpool v0.1.11 // indirect + github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect + github.com/vmihailenco/tagparser v0.1.1 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect + google.golang.org/appengine v1.6.6 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + mellium.im/sasl v0.2.1 // indirect ) diff --git a/go.sum b/go.sum index 4f7ca33..460dcf5 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,30 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/codemodus/kace v0.5.1 h1:4OCsBlE2c/rSJo375ggfnucv9eRzge/U5LrrOZd47HA= +github.com/codemodus/kace v0.5.1/go.mod h1:coddaHoX1ku1YFSe4Ip0mL9kQjJvKkzb9CfIdG1YR04= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-pg/pg/v9 v9.2.1 h1:4rWNJkj+aPuDFqgieTzNhHBuYaXREh3yaB9NlBerFys= +github.com/go-pg/pg/v9 v9.2.1/go.mod h1:fG8qbL+ei4e/fCZLHK+Z+/7b9B+pliZtbpaucG4/YNQ= +github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= +github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -20,14 +33,42 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -39,13 +80,21 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/segmentio/encoding v0.1.15 h1:btgfyAuFo3uLw7eOrRDPo8H4Bc881+bSPHzAEe0ukho= +github.com/segmentio/encoding v0.1.15/go.mod h1:RWhr02uzMB9gQC1x+MfYxedtmBibb9cZ6Vv9VxRSSbw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -56,25 +105,96 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= +github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= +github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= +mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/main.go b/main.go index a3d31a7..2c38d9e 100644 --- a/main.go +++ b/main.go @@ -4,15 +4,12 @@ import ( // "fmt" "net/http" "github.com/gin-gonic/gin" + models "harshsinghvi/golang-postgres-kubernetes/models" + "harshsinghvi/golang-postgres-kubernetes/database" ) -type Todo struct { - ID string `json:"id"` - Text string `json:"text"` - Completed bool `json:"completed"` - // Date float64 `json:"date"` // TODO: implement latter -} -var TODOS = []Todo{ + +var TODOS = []models.Todo{ {ID: "1", Text: "Task 1", Completed: false}, {ID: "2", Text: "Task 2", Completed: false}, {ID: "3", Text: "Task 3", Completed: false}, @@ -39,7 +36,7 @@ func getTodos(c *gin.Context) { } func postTodos(c *gin.Context) { - var newTodo Todo + var newTodo models.Todo // Call BindJSON to bind the received JSON to if err := c.BindJSON(&newTodo); err != nil { @@ -64,7 +61,7 @@ func postTodos(c *gin.Context) { func updateTodos(c *gin.Context){ id := c.Param("id") - var updateTodo Todo + var updateTodo models.Todo // Call BindJSON to bind the received JSON to if err := c.BindJSON(&updateTodo); err != nil { @@ -104,19 +101,36 @@ func deleteTodos(c *gin.Context){ c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no ID"}) } -func healthAndReadinessHandler(c *gin.Context){ +func healthHandler(c *gin.Context){ + c.IndentedJSON(http.StatusOK, gin.H {"message": "OK"}) +} +func readinessHandler(c *gin.Context){ + if !database.IsDtabaseReady() { + c.IndentedJSON(http.StatusServiceUnavailable, gin.H {"message": "server not ready"}) + return + } c.IndentedJSON(http.StatusOK, gin.H {"message": "OK"}) } func main() { + database.Connect(); + database.CreateTodoTable(); + router := gin.Default() - router.GET("/todos", getTodos) - router.POST("/todos", postTodos) - router.PUT("/todos/:id", updateTodos) - router.DELETE("/todos/:id", deleteTodos) + router.GET("/v1/todo", getTodos) + router.POST("v1/todo", postTodos) + router.PUT("v1/todo/:id", updateTodos) + router.DELETE("v1/todo/:id", deleteTodos) + + router.GET("/v2/todo", database.GetAllTodos) + router.GET("/v2/todos", database.GetAllTodos) + router.GET("/v2/todo/:id", database.GetSingleTodo) + router.POST("v2/todo", database.CreateTodo) + router.PUT("v2/todo/:id", database.EditTodo) + router.DELETE("v2/todo/:id", database.DeleteTodo) - router.GET("/health", healthAndReadinessHandler) - router.GET("/readiness", healthAndReadinessHandler) + router.GET("/health", healthHandler) + router.GET("/readiness", readinessHandler) router.Run(":8080") } diff --git a/models/todo.go b/models/todo.go new file mode 100644 index 0000000..38d5cbb --- /dev/null +++ b/models/todo.go @@ -0,0 +1,13 @@ +package models + +import "time" + +type Todo struct { + ID string `json:"id"` + Text string `json:"text"` + Completed bool `json:"completed"` + // Date float64 `json:"date"` // TODO: implement latter + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + From 6e9bf200ce94bf1a856c1a70403248528f925e1d Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 18:37:05 +0530 Subject: [PATCH 09/22] Change directory structure --- README.md | 75 +++++++------------ {kubernetes => k8s-deployments}/database.yml | 0 .../deployment.yml | 0 .../.dockerconfigjson | 0 .../iam_policy.json | 0 .../loadgenerator.yml | 0 .../matrics-server.yaml | 0 7 files changed, 28 insertions(+), 47 deletions(-) rename {kubernetes => k8s-deployments}/database.yml (100%) rename {kubernetes => k8s-deployments}/deployment.yml (100%) rename .dockerconfigjson => k8s-eks-system/.dockerconfigjson (100%) rename iam_policy.json => k8s-eks-system/iam_policy.json (100%) rename loadgenerator.yml => k8s-eks-system/loadgenerator.yml (100%) rename {kubernetes => k8s-eks-system}/matrics-server.yaml (100%) diff --git a/README.md b/README.md index 4259dca..7047433 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,21 @@ ## resources -- Linkedin Learning (kubernetes, golang courses) -- udemy hnsr course db -- https://go.dev/doc/tutorial/web-service-gin -- https://dev.to/ramu_mangalarapu/building-rest-apis-in-golang-go-gin-with-persistence-database-postgres-4616 -- https://www.coding-bootcamps.com/blog/build-containerized-applications-with-golang-on-kubernetes.html -- https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html -- https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ -- https://dev.to/asizikov/using-github-container-registry-with-kubernetes-38fb ghcr.io kubernetes -- https://aws.amazon.com/blogs/containers/using-alb-ingress-controller-with-amazon-eks-on-fargate/ fargarte exose services - -- https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html alb imp -- https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html eks ingress imp -- https://artifacthub.io/packages/helm/metrics-server/metrics-server install Matrics server -- https://docs.aws.amazon.com/eks/latest/userguide/metrics-server.html matrics server -- https://levelup.gitconnected.com/how-to-deploy-a-multi-container-two-tier-go-application-in-eks-fargate-6266494f5bcf go and postgres eks +- +- +- +- +- + +- ghcr.io kubernetes + +- fargarte exose services +- alb imp +- eks ingress imp + +- install Matrics server +- matrics server +- go and postgres eks ## TODOS @@ -38,6 +38,7 @@ - autoscale postgress deployment ## AWS Resources created (tags: pingsafe-test) + - EKS IAM Role - EKS Cluster - ECS Cluster @@ -45,8 +46,8 @@ docker login -u AWS -p $(aws ecr get-login-password --region ap-south-1) 194505915562.dkr.ecr.ap-south-1.amazonaws.com +## Build docker image for eks faragete -## Build docker image for eks faragete // login ghcr docker export CR_PAT=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 echo $CR_PAT | docker login ghcr.io -u harshsinghvi --password-stdin @@ -55,8 +56,18 @@ docker buildx build --platform=linux/amd64 -t ghcr.io/harshsinghvi/golang-postgr docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest -``` +## K8S procedure + +1. eksctl faragete cluster `eksctl create cluster --name cluster --region ap-south-1 --fargate` +1. cluster ALB ingress +1. setup matrics server (for HPA) from YML +1. sertup efs (elastic file storage) +1. ghcr secrets for image +1. deploy services (yml files) yml files includes HPA +## AUTOSCALE LOGS + +```text go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 2 19m go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 19m go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 19m @@ -176,33 +187,3 @@ go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 3 53m go-todo-api-hpa Deployment/go-todo-api 0%/30% 1 10 3 53m ``` - -aws efs create-mount-target \ - --file-system-id $file_system_id \ - --subnet-id subnet-0f8e0a7152ce63763 \ - --security-groups $security_group_id - -aws efs create-mount-target \ - --file-system-id $file_system_id \ - --subnet-id subnet-0e2824fc49bdcd202 \ - --security-groups $security_group_id - -aws efs create-mount-target \ - --file-system-id $file_system_id \ - --subnet-id subnet-028474cfc7ca5c2c5 \ - --security-groups $security_group_id - -aws efs create-mount-target \ - --file-system-id $file_system_id \ - --subnet-id subnet-060db0728f89d0203 \ - --security-groups $security_group_id - -aws efs create-mount-target \ - --file-system-id $file_system_id \ - --subnet-id subnet-00782a5c917b7ae74 \ - --security-groups $security_group_id - -aws efs create-mount-target \ - --file-system-id $file_system_id \ - --subnet-id subnet-0a7fb187cb42744b1 \ - --security-groups $security_group_id diff --git a/kubernetes/database.yml b/k8s-deployments/database.yml similarity index 100% rename from kubernetes/database.yml rename to k8s-deployments/database.yml diff --git a/kubernetes/deployment.yml b/k8s-deployments/deployment.yml similarity index 100% rename from kubernetes/deployment.yml rename to k8s-deployments/deployment.yml diff --git a/.dockerconfigjson b/k8s-eks-system/.dockerconfigjson similarity index 100% rename from .dockerconfigjson rename to k8s-eks-system/.dockerconfigjson diff --git a/iam_policy.json b/k8s-eks-system/iam_policy.json similarity index 100% rename from iam_policy.json rename to k8s-eks-system/iam_policy.json diff --git a/loadgenerator.yml b/k8s-eks-system/loadgenerator.yml similarity index 100% rename from loadgenerator.yml rename to k8s-eks-system/loadgenerator.yml diff --git a/kubernetes/matrics-server.yaml b/k8s-eks-system/matrics-server.yaml similarity index 100% rename from kubernetes/matrics-server.yaml rename to k8s-eks-system/matrics-server.yaml From a5f532c0ce6e896d36b9981258a7a8d08e69aa8f Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 19:29:28 +0530 Subject: [PATCH 10/22] Update docs and refs --- README.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7047433..f9cee49 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,13 @@ - - - -- - ghcr.io kubernetes - fargarte exose services - alb imp - eks ingress imp +- HPA - install Matrics server - matrics server @@ -37,15 +37,6 @@ - deploy postgress to Kubernetes - autoscale postgress deployment -## AWS Resources created (tags: pingsafe-test) - -- EKS IAM Role -- EKS Cluster -- ECS Cluster -- vpc subnets - -docker login -u AWS -p $(aws ecr get-login-password --region ap-south-1) 194505915562.dkr.ecr.ap-south-1.amazonaws.com - ## Build docker image for eks faragete // login ghcr docker @@ -65,8 +56,9 @@ docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest 1. ghcr secrets for image 1. deploy services (yml files) yml files includes HPA -## AUTOSCALE LOGS +## AUTOSCALE LOGS HPA +`kubectl get hpa php-apache --watch` ```text go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 2 19m go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 19m @@ -74,7 +66,6 @@ go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 20m go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m - go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 1 21m go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m From 1725c408f040db0417905532559b5f9fb9d649f2 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 21:25:26 +0530 Subject: [PATCH 11/22] Working Postgress todo api --- database/database.go | 15 +++++++++++---- docker-compose/postgres/.gitkeep | 0 go.mod | 1 + go.sum | 2 ++ main.go | 7 +++++++ models/todo.go | 1 - utils/utils.go | 13 +++++++++++++ 7 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 docker-compose/postgres/.gitkeep create mode 100644 utils/utils.go diff --git a/database/database.go b/database/database.go index df28c95..899da21 100644 --- a/database/database.go +++ b/database/database.go @@ -2,6 +2,7 @@ package database import ( . "harshsinghvi/golang-postgres-kubernetes/models" + "harshsinghvi/golang-postgres-kubernetes/utils" "github.com/go-pg/pg/v9" orm "github.com/go-pg/pg/v9/orm" @@ -26,11 +27,17 @@ func GetDatabase() *pg.DB { } func Connect() *pg.DB { + DB_HOST := utils.GetEnv("DB_HOST", "localhost") + DB_PORT := utils.GetEnv("DB_PORT", "5432") + DB_USER := utils.GetEnv("DB_USER", "postgres") + DB_PASSWORD := utils.GetEnv("DB_PASSWORD", "postgres") + DB_NAME := utils.GetEnv("DB_NAME", "postgres") + opts := &pg.Options{ - User: "postgres", - Password: "postgres", - Addr: "localhost:5432", - Database: "postgres", + User: DB_USER, + Password: DB_PASSWORD, + Addr: DB_HOST+":"+DB_PORT, + Database: DB_NAME, } connection = pg.Connect(opts) if connection == nil { diff --git a/docker-compose/postgres/.gitkeep b/docker-compose/postgres/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/go.mod b/go.mod index abc0809..fe41666 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/go-pg/pg/v9 v9.2.1 github.com/google/uuid v1.4.0 + github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 ) diff --git a/go.sum b/go.sum index 460dcf5..30285ae 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,8 @@ github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= diff --git a/main.go b/main.go index 2c38d9e..2ea553b 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,8 @@ import ( "github.com/gin-gonic/gin" models "harshsinghvi/golang-postgres-kubernetes/models" "harshsinghvi/golang-postgres-kubernetes/database" + "log" + "github.com/joho/godotenv" ) @@ -113,6 +115,11 @@ func readinessHandler(c *gin.Context){ } func main() { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + database.Connect(); database.CreateTodoTable(); diff --git a/models/todo.go b/models/todo.go index 38d5cbb..6271184 100644 --- a/models/todo.go +++ b/models/todo.go @@ -6,7 +6,6 @@ type Todo struct { ID string `json:"id"` Text string `json:"text"` Completed bool `json:"completed"` - // Date float64 `json:"date"` // TODO: implement latter CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..3ee1f7f --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,13 @@ +package utils + +import ( + "os" +) + +func GetEnv(varNameString string, defaultValue string) string { + var varValue string; + if varValue = os.Getenv(varNameString); varNameString == "" { + varValue = defaultValue + } + return varValue; +} \ No newline at end of file From 84cccc38b3e334250fc03970a844baf476787ba4 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Thu, 16 Nov 2023 22:00:06 +0530 Subject: [PATCH 12/22] Working Kube deployment --- .dockerignore | 1 + .gitignore | 3 +- README.md | 166 ++++++++++++++++++++++++++++++--- database/database.go | 3 +- docker-compose.yml | 38 ++++++++ k8s-deployments/database.yml | 34 ++++--- k8s-deployments/deployment.yml | 27 ++---- k8s-deployments/secrets.yml | 43 +++++++++ main.go | 2 +- 9 files changed, 271 insertions(+), 46 deletions(-) create mode 100644 .dockerignore create mode 100644 docker-compose.yml create mode 100644 k8s-deployments/secrets.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..aab3c9e --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +docker-compose/postgres diff --git a/.gitignore b/.gitignore index 512d187..d7f611d 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,5 @@ Temporary Items # End of https://www.toptal.com/developers/gitignore/api/go,macos -.env \ No newline at end of file +.env +docker-compose/ diff --git a/README.md b/README.md index f9cee49..e3f628e 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ - matrics server - go and postgres eks +- golang postgres api + ## TODOS - Golang API @@ -37,28 +39,31 @@ - deploy postgress to Kubernetes - autoscale postgress deployment -## Build docker image for eks faragete - -// login ghcr docker -export CR_PAT=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 -echo $CR_PAT | docker login ghcr.io -u harshsinghvi --password-stdin - -docker buildx build --platform=linux/amd64 -t ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest . - -docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest - ## K8S procedure 1. eksctl faragete cluster `eksctl create cluster --name cluster --region ap-south-1 --fargate` 1. cluster ALB ingress 1. setup matrics server (for HPA) from YML -1. sertup efs (elastic file storage) -1. ghcr secrets for image +1. sertup efs (elastic file storage) get file_system_id and replace volumeHandle: fs-1234567899 in database.yml +1. ghcr secrets for image replace required fields in secrets.yml + 1. deploy services (yml files) yml files includes HPA +## commands + +```bash + +kubectl rollout restart deployment/name # to update image +kubectl get ingress # ingress exposed url + +aws eks update-kubeconfig --region ap-south-1 --name cluster +kubectl exec --stdin --tty pod/postgres-0 -- /bin/bash +``` + ## AUTOSCALE LOGS HPA `kubectl get hpa php-apache --watch` + ```text go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 2 19m go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 19m @@ -178,3 +183,140 @@ go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 3 53m go-todo-api-hpa Deployment/go-todo-api 0%/30% 1 10 3 53m ``` + +## GHCR image build and push + +`https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry` + +```bash +docker buildx build --platform=linux/amd64 -t golang-postgres-kubernetes . + +docker tag golang-postgres-kubernetes ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest + +docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest +``` + +## ELB and ingress SETUP + +```bash +ACCOUNT_ID= # aws sts get-caller-identity +AWS_EKS_CLUSTER_NAME=cluster +AWS_EKS_CLUSTER_REGION=ap-south-1 + +AWS_EKS_CLUSTER_VPC_ID=$(aws eks describe-cluster \ + --name $AWS_EKS_CLUSTER_NAME \ + --query "cluster.resourcesVpcConfig.vpcId" \ + --output text) + +# AWS_EKS_CLUSTER_VPC_ID= # console>cloudformations + +curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/install/iam_policy.json + +aws iam create-policy \ + --policy-name AWSLoadBalancerControllerIAMPolicy \ + --policy-document file://iam_policy.json + +eksctl utils associate-iam-oidc-provider --region=ap-south-1 --cluster=cluster --approve + +eksctl create iamserviceaccount \ + --cluster=cluster \ + --namespace=kube-system \ + --name=aws-load-balancer-controller \ + --role-name AmazonEKSLoadBalancerControllerRole \ + --attach-policy-arn=arn:aws:iam::194505915562:policy/AWSLoadBalancerControllerIAMPolicy \ + --approve + +helm repo add eks https://aws.github.io/eks-charts + +aws sts get-caller-identity + +helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ + -n kube-system \ + --set clusterName=cluster \ + --set serviceAccount.create=false \ + --set serviceAccount.name=aws-load-balancer-controller \ + --set region=ap-south-1 \ + --set vpcId=vpc-07ae5f71518dd2545 + +kubectl get deployment -n kube-system aws-load-balancer-controller + + # during upgrade + kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master" + + helm upgrade aws-load-balancer-controller eks/aws-load-balancer-controller \ + -n kube-system \ + --set clusterName=cluster \ + --set serviceAccount.create=false \ + --set serviceAccount.name=aws-load-balancer-controller \ + --set region=ap-south-1 \ + --set vpcId=vpc-07ae5f71518dd2545 +``` + +## EFS Setup + +```bash +AWS_EKS_CLUSTER_NAME=cluster +AWS_EKS_CLUSTER_REGION=ap-south-1 + +vpc_id=$(aws eks describe-cluster \ + --name $AWS_EKS_CLUSTER_NAME \ + --query "cluster.resourcesVpcConfig.vpcId" \ + --output text) + +cidr_range=$(aws ec2 describe-vpcs \ + --vpc-ids $vpc_id \ + --query "Vpcs[].CidrBlock" \ + --output text \ + --region $AWS_EKS_CLUSTER_REGION) + + +security_group_id=$(aws ec2 create-security-group \ + --group-name MyEfsSecurityGroup \ + --description "My EFS security group" \ + --vpc-id $vpc_id \ + --output text) + +aws ec2 authorize-security-group-ingress \ + --group-id $security_group_id \ + --protocol tcp \ + --port 2049 \ + --cidr $cidr_range + +file_system_id=$(aws efs create-file-system \ + --region ap-south-1 \ + --performance-mode generalPurpose \ + --query 'FileSystemId' \ + --output text) + + +aws ec2 describe-subnets \ + --filters "Name=vpc-id,Values=$vpc_id" \ + --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \ + --output table + +# run for each subnet +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-09555c7ce2147f642 \ + --security-groups $security_group_id +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-019b6e706b2823a7b \ + --security-groups $security_group_id +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-0324d7a94eb3afd09 \ + --security-groups $security_group_id +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-04d07f3812cf78123 \ + --security-groups $security_group_id +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-0ee5c658df8ef377c \ + --security-groups $security_group_id +aws efs create-mount-target \ + --file-system-id $file_system_id \ + --subnet-id subnet-0360ff2918bf5fceb \ + --security-groups $security_group_id +``` diff --git a/database/database.go b/database/database.go index 899da21..7c9b283 100644 --- a/database/database.go +++ b/database/database.go @@ -36,7 +36,7 @@ func Connect() *pg.DB { opts := &pg.Options{ User: DB_USER, Password: DB_PASSWORD, - Addr: DB_HOST+":"+DB_PORT, + Addr: DB_HOST + ":" + DB_PORT, Database: DB_NAME, } connection = pg.Connect(opts) @@ -45,6 +45,7 @@ func Connect() *pg.DB { os.Exit(100) } log.Printf("Connected to db") + database_ready = true return connection } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..acc121d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,38 @@ +version: '3' +services: + app: + container_name: go-todo-api + build: . + ports: + - 8080:8080 + restart: on-failure + depends_on: + - postgres + networks: + - fullstack + environment: + - PORT=${PORT} + - POSTGRES_URL=postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable + + postgres: + image: postgres:latest + container_name: postgres + environment: + - POSTGRES_USER=${DB_USER} + - POSTGRES_PASSWORD=${DB_PASSWORD} + - POSTGRES_DB=${DB_NAME} + - DATABASE_HOST=${DB_HOST} + ports: + - '5432:5432' + volumes: + - ./docker-compose/postgres:/var/lib/postgresql/data + networks: + - fullstack + +volumes: + database_postgres: + +# Networks to be created to facilitate communication between containers +networks: + fullstack: + driver: bridge diff --git a/k8s-deployments/database.yml b/k8s-deployments/database.yml index 9644aa4..bdec7a4 100644 --- a/k8s-deployments/database.yml +++ b/k8s-deployments/database.yml @@ -13,7 +13,7 @@ spec: storageClassName: efs-sc csi: driver: efs.csi.aws.com - volumeHandle: fs-07cbaab02f39869e2 + volumeHandle: fs-0b9f5c3cf12064d83 --- apiVersion: v1 @@ -35,17 +35,6 @@ metadata: name: efs-sc provisioner: efs.csi.aws.com ---- -apiVersion: v1 -kind: Secret -metadata: - name: postgres-secret -type: Opaque -stringData: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - --- apiVersion: apps/v1 kind: StatefulSet # Type of the kubernetes resource @@ -60,7 +49,7 @@ spec: app: postgres tier: postgres replicas: 1 - template: # Template for the Pods in this statefulset + template: # Template for the Pods in this statefulset metadata: labels: # Labels to be applied to the Pods in this statefulset app: postgres @@ -76,6 +65,11 @@ spec: ports: - containerPort: 5432 # The port that the container exposes name: postgres + resources: + limits: + cpu: "500m" + requests: + cpu: "200m" volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-persistent-storage # This name should match the name specified in `volumes.name` @@ -99,3 +93,17 @@ spec: selector: # Selects any Pod with labels `app=fullstack-postgres,tier=postgres` app: postgres tier: postgres + +--- +apiVersion: autoscaling/v1 +kind: HorizontalPodAutoscaler +metadata: + name: postgres-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: postgres + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 80 \ No newline at end of file diff --git a/k8s-deployments/deployment.yml b/k8s-deployments/deployment.yml index 4929e76..09a02d4 100644 --- a/k8s-deployments/deployment.yml +++ b/k8s-deployments/deployment.yml @@ -4,7 +4,7 @@ kind: Deployment # Type of Kubernetes resource metadata: name: go-todo-api # Name of the Kubernetes resource spec: - replicas: 3 # Number of pods to run at any given time + replicas: 1 # Number of pods to run at any given time selector: matchLabels: app: go-todo-api # This deployment applies to any Pods matching the specified label @@ -19,13 +19,16 @@ spec: - name: go-todo-api image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest imagePullPolicy: IfNotPresent # Always + envFrom: + - secretRef: + name: app-secret ports: - containerPort: 8080 # Should match the port number that the Go application listens on resources: limits: - cpu: '500m' + cpu: "500m" requests: - cpu: '200m' + cpu: "200m" livenessProbe: # To check the health of the Pod httpGet: path: /health @@ -64,7 +67,7 @@ metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip - + # alb.ingress.kubernetes.io/group.name: kube-alb-group #Use this to share ALB among multiple ingresses. #CostEffective # alb.ingress.kubernetes.io/load-balancer-name: kube-alb # give ALB a meaningfull name otherwise a random name is assigned by AWS. # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:eu-west-1:XXXX:certificate/YYYY" # Get it by $ aws acm list-certificates @@ -83,17 +86,6 @@ spec: port: number: 8080 ---- -kind: Secret -type: kubernetes.io/dockerconfigjson -apiVersion: v1 -metadata: - name: dockerconfigjson-github-com - labels: - app: app-name -data: - .dockerconfigjson: eyAiYXV0aHMiOiB7ICJnaGNyLmlvIjogeyAiYXV0aCI6ImFHRnljMmh6YVc1bmFIWnBPbWRvY0Y5UU1FOHdZbXRXU0VwMVYzbHJObWRPVnpaQ1lWYzRRMFY2Y25sTFVXZ3hkRkp1UlVrPSIgfSB9IH0= - --- apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler @@ -104,7 +96,6 @@ spec: apiVersion: apps/v1 kind: Deployment name: go-todo-api - minReplicas: 2 + minReplicas: 1 maxReplicas: 10 - targetCPUUtilizationPercentage: 30 - + targetCPUUtilizationPercentage: 80 diff --git a/k8s-deployments/secrets.yml b/k8s-deployments/secrets.yml new file mode 100644 index 0000000..066bda0 --- /dev/null +++ b/k8s-deployments/secrets.yml @@ -0,0 +1,43 @@ +# DEPLOYMENT SECRET +--- +kind: Secret +type: kubernetes.io/dockerconfigjson +apiVersion: v1 +metadata: + name: dockerconfigjson-github-com + labels: + app: app-name +data: + .dockerconfigjson: eyAiYXV0aHMiOiB7ICJnaGNyLmlvIjogeyAiYXV0aCI6ImFHRnljMmh6YVc1bmFIWnBPbWRvY0Y5UU1FOHdZbXRXU0VwMVYzbHJObWRPVnpaQ1lWYzRRMFY2Y25sTFVXZ3hkRkp1UlVrPSIgfSB9IH0= + +# App Secrets +--- +apiVersion: v1 +kind: Secret +metadata: + name: app-secret +type: Opaque +stringData: + # Postgres Config + DB_HOST: postgres + DB_DRIVER: postgres + DB_USER: postgres + DB_PASSWORD: postgres + DB_NAME: postgres + DB_PORT: "5432" + #Go app PORT configuration + PORT: "8080" + POSTGRES_URL: postgres://postgres:postgres@postgres:5432/postgres?sslmode=disable # Currently hardcoding DB parameters, could use nested variables as future improvement + # POSTGRES_URL: postgres://:@:5432/simple-service?sslmode=disable # Currently hardcoding DB parameters, could use nested variables as future improvement + +# Database secrets +--- +apiVersion: v1 +kind: Secret +metadata: + name: postgres-secret +type: Opaque +stringData: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres diff --git a/main.go b/main.go index 2ea553b..f2f7f0a 100644 --- a/main.go +++ b/main.go @@ -117,7 +117,7 @@ func readinessHandler(c *gin.Context){ func main() { err := godotenv.Load() if err != nil { - log.Fatal("Error loading .env file") + log.Printf("Error loading .env file") } database.Connect(); From fcba6069a292675dd105c991803ba74d68e7efc8 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 00:48:31 +0530 Subject: [PATCH 13/22] Setup GH Actions --- .github/workflows/docker-image.yml | 31 ++++++++++++++++++++++++++++++ Dockerfile | 2 ++ 2 files changed, 33 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..01c6fb3 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,31 @@ +name: ci + +on: + push: + branches: + - "main" + - "master" + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to ghcr + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{github.actor}} + password: ${{secrets.GH_TOKEN}} + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest diff --git a/Dockerfile b/Dockerfile index 26f5619..efca79e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,7 @@ # STEP 1 build executable binary ############################ FROM golang:alpine AS builder +LABEL org.opencontainers.image.source="https://github.com/harshsinghvi/golang-postgres-kubernetes" # Install git. # Git is required for fetching the dependencies. RUN apk update && apk add --no-cache 'git=~2' @@ -22,6 +23,7 @@ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /go/main . # STEP 2 build a small image ############################ FROM alpine +LABEL org.opencontainers.image.source="https://github.com/harshsinghvi/golang-postgres-kubernetes" WORKDIR / From c840eb29324a0a427599b317eb6b71e432a3237b Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 03:01:58 +0530 Subject: [PATCH 14/22] Update Routes and directory structure --- .vscode/launch.json | 15 +++ controllers/controllers.go | 127 +++++++++++++++++++++++ controllers_old/controllers_old.go | 95 ++++++++++++++++++ database/database.go | 146 +++++---------------------- go.mod | 8 +- go.sum | 55 ++++++++++ main.go | 156 +++++++---------------------- 7 files changed, 356 insertions(+), 246 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 controllers/controllers.go create mode 100644 controllers_old/controllers_old.go diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5ac2bb4 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "./main.go" + } + ] +} \ No newline at end of file diff --git a/controllers/controllers.go b/controllers/controllers.go new file mode 100644 index 0000000..c874245 --- /dev/null +++ b/controllers/controllers.go @@ -0,0 +1,127 @@ +package controllers + +import ( + "github.com/gin-gonic/gin" + // "github.com/go-pg/pg/v9" + guuid "github.com/google/uuid" + "log" + "net/http" + "time" + + "harshsinghvi/golang-postgres-kubernetes/database" + "harshsinghvi/golang-postgres-kubernetes/models" +) + +// var (connection *pg.DB )// = *database.GetDatabase() + +// init() { +// connection = = *database.GetDatabase() +// } + +// connection := *database.GetDatabase() + +func GetAllTodos(c *gin.Context) { + + var todos []models.Todo + err := database.Connection.Model(&todos).Select() + if err != nil { + log.Printf("Error while getting all todos, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "All Todos", + "data": todos, + }) +} + +func GetSingleTodo(c *gin.Context) { + todoId := c.Param("id") + todo := &models.Todo{ID: todoId} + err := database.Connection.Select(todo) + if err != nil { + log.Printf("Error while getting a single todo, Reason: %v\n", err) + c.JSON(http.StatusNotFound, gin.H{ + "status": http.StatusNotFound, + "message": "Todo not found", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "Single Todo", + "data": todo, + }) +} + +func CreateTodo(c *gin.Context) { + var todo models.Todo + c.BindJSON(&todo) + + text := todo.Text + id := guuid.New().String() + + insertError := database.Connection.Insert(&models.Todo{ + ID: id, + Text: text, + Completed: false, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + }) + + if insertError != nil { + log.Printf("Error while inserting new todo into db, Reason: %v\n", insertError) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } + + c.JSON(http.StatusCreated, gin.H{ + "status": http.StatusCreated, + "message": "Todo created Successfully", + }) +} + +func EditTodo(c *gin.Context) { + todoId := c.Param("id") + var todo models.Todo + c.BindJSON(&todo) + completed := todo.Completed + _, err := database.Connection.Model(&models.Todo{}).Set("completed = ?", completed).Where("id = ?", todoId).Update() + if err != nil { + log.Printf("Error, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": 500, + "message": "Something went wrong", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": 200, + "message": "Todo Edited Successfully", + }) +} + +func DeleteTodo(c *gin.Context) { + todoId := c.Param("id") + todo := &models.Todo{ID: todoId} + err := database.Connection.Delete(todo) + if err != nil { + log.Printf("Error while deleting a single todo, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } + c.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "Todo deleted successfully", + }) +} diff --git a/controllers_old/controllers_old.go b/controllers_old/controllers_old.go new file mode 100644 index 0000000..fd06cf8 --- /dev/null +++ b/controllers_old/controllers_old.go @@ -0,0 +1,95 @@ +package controllers_old + +import ( + "github.com/gin-gonic/gin" + "harshsinghvi/golang-postgres-kubernetes/models" + "net/http" +) + +var TODOS = []models.Todo{ + {ID: "1", Text: "Task 1", Completed: false}, + {ID: "2", Text: "Task 2", Completed: false}, + {ID: "3", Text: "Task 3", Completed: false}, +} + +func GetTodos(c *gin.Context) { + id := c.Query("id") + // completed := c.Query("completed") == "true" // TODO: implement this filter + + if id == "" { + c.IndentedJSON(http.StatusOK, TODOS) + return + } + + for _, a := range TODOS { + if a.ID == id { + c.IndentedJSON(http.StatusOK, a) + return + } + } + c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "not found"}) +} + +func PostTodos(c *gin.Context) { + var newTodo models.Todo + + // Call BindJSON to bind the received JSON to + if err := c.BindJSON(&newTodo); err != nil { + return + } + + if newTodo.Text == "" { + c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no text"}) + return + } + + for _, a := range TODOS { + if a.ID == newTodo.ID { + c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "Duplicate ID"}) + return + } + } + // Add the new album to the slice. + TODOS = append(TODOS, newTodo) + c.IndentedJSON(http.StatusCreated, newTodo) +} + +func UpdateTodos(c *gin.Context) { + id := c.Param("id") + var updateTodo models.Todo + + // Call BindJSON to bind the received JSON to + if err := c.BindJSON(&updateTodo); err != nil { + return + } + + if updateTodo.ID == "" { + c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no ID"}) + return + } + + for index, a := range TODOS { + if a.ID == id { + if updateTodo.Text != "" { + TODOS[index].Text = updateTodo.Text + } + TODOS[index].Completed = updateTodo.Completed + c.IndentedJSON(http.StatusOK, TODOS[index]) + return + } + } + c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "invalid ID"}) +} + +func DeleteTodos(c *gin.Context) { + id := c.Param("id") + + for index, a := range TODOS { + if a.ID == id { + TODOS = append(TODOS[:index], TODOS[index+1:]...) + c.IndentedJSON(http.StatusOK, TODOS) + return + } + } + c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no ID"}) +} diff --git a/database/database.go b/database/database.go index 7c9b283..d3fbce4 100644 --- a/database/database.go +++ b/database/database.go @@ -1,29 +1,22 @@ package database import ( - . "harshsinghvi/golang-postgres-kubernetes/models" - "harshsinghvi/golang-postgres-kubernetes/utils" - "github.com/go-pg/pg/v9" orm "github.com/go-pg/pg/v9/orm" - guuid "github.com/google/uuid" + "harshsinghvi/golang-postgres-kubernetes/models" + "harshsinghvi/golang-postgres-kubernetes/utils" "log" - "os" - - "github.com/gin-gonic/gin" - "net/http" - "time" ) var database_ready = false -var connection *pg.DB +var Connection *pg.DB func IsDtabaseReady() bool { return database_ready } -func GetDatabase() *pg.DB { - return connection +func GetDatabase() **pg.DB { + return &Connection } func Connect() *pg.DB { @@ -39,14 +32,25 @@ func Connect() *pg.DB { Addr: DB_HOST + ":" + DB_PORT, Database: DB_NAME, } - connection = pg.Connect(opts) - if connection == nil { - log.Printf("Failed to connect") - os.Exit(100) + + Connection = pg.Connect(opts) + + if Connection == nil { + log.Printf("Failed to connect to database") + return nil + } + + ctx := Connection.Context() + var version string + _, err := Connection.QueryOneContext(ctx, pg.Scan(&version), "SELECT version()") + if err != nil { + log.Printf("Failed to connect to database") + return nil } + log.Printf("Connected to db") database_ready = true - return connection + return Connection } // Create User Table @@ -54,7 +58,8 @@ func CreateTodoTable() error { opts := &orm.CreateTableOptions{ IfNotExists: true, } - createError := connection.CreateTable(&Todo{}, opts) + + createError := Connection.CreateTable(&models.Todo{}, opts) if createError != nil { log.Printf("Error while creating todo table, Reason: %v\n", createError) return createError @@ -62,108 +67,3 @@ func CreateTodoTable() error { log.Printf("Todo table created") return nil } - -func GetAllTodos(c *gin.Context) { - var todos []Todo - err := connection.Model(&todos).Select() - if err != nil { - log.Printf("Error while getting all todos, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) - return - } - c.JSON(http.StatusOK, gin.H{ - "status": http.StatusOK, - "message": "All Todos", - "data": todos, - }) -} - -func GetSingleTodo(c *gin.Context) { - todoId := c.Param("id") - todo := &Todo{ID: todoId} - err := connection.Select(todo) - if err != nil { - log.Printf("Error while getting a single todo, Reason: %v\n", err) - c.JSON(http.StatusNotFound, gin.H{ - "status": http.StatusNotFound, - "message": "Todo not found", - }) - return - } - c.JSON(http.StatusOK, gin.H{ - "status": http.StatusOK, - "message": "Single Todo", - "data": todo, - }) -} - -func CreateTodo(c *gin.Context) { - var todo Todo - c.BindJSON(&todo) - - text := todo.Text - id := guuid.New().String() - - insertError := connection.Insert(&Todo{ - ID: id, - Text: text, - Completed: false, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - }) - - if insertError != nil { - log.Printf("Error while inserting new todo into db, Reason: %v\n", insertError) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) - return - } - - c.JSON(http.StatusCreated, gin.H{ - "status": http.StatusCreated, - "message": "Todo created Successfully", - }) -} - -func EditTodo(c *gin.Context) { - todoId := c.Param("id") - var todo Todo - c.BindJSON(&todo) - completed := todo.Completed - _, err := connection.Model(&Todo{}).Set("completed = ?", completed).Where("id = ?", todoId).Update() - if err != nil { - log.Printf("Error, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": 500, - "message": "Something went wrong", - }) - return - } - c.JSON(http.StatusOK, gin.H{ - "status": 200, - "message": "Todo Edited Successfully", - }) -} - -func DeleteTodo(c *gin.Context) { - todoId := c.Param("id") - todo := &Todo{ID: todoId} - err := connection.Delete(todo) - if err != nil { - log.Printf("Error while deleting a single todo, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) - return - } - c.JSON(http.StatusOK, gin.H{ - "status": http.StatusOK, - "message": "Todo deleted successfully", - }) -} diff --git a/go.mod b/go.mod index fe41666..b1ae86a 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21.1 require ( github.com/gin-gonic/gin v1.9.1 + github.com/go-pg/pg/v10 v10.11.2 github.com/go-pg/pg/v9 v9.2.1 github.com/google/uuid v1.4.0 github.com/joho/godotenv v1.5.1 @@ -31,11 +32,14 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/segmentio/encoding v0.1.15 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/vmihailenco/bufpool v0.1.11 // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect - github.com/vmihailenco/tagparser v0.1.1 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect + github.com/vmihailenco/tagparser v0.1.2 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect @@ -44,5 +48,5 @@ require ( google.golang.org/appengine v1.6.6 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - mellium.im/sasl v0.2.1 // indirect + mellium.im/sasl v0.3.1 // indirect ) diff --git a/go.sum b/go.sum index 30285ae..59ec849 100644 --- a/go.sum +++ b/go.sum @@ -15,12 +15,15 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-pg/pg/v10 v10.11.2 h1:LPMK5KDe6P+EjuE/iv99gwGx0XGVOZug7Ijx0ekDiE8= +github.com/go-pg/pg/v10 v10.11.2/go.mod h1:ExJWndhDNNftBdw1Ow83xqpSf4WMSJK8urmXD5VXS1I= github.com/go-pg/pg/v9 v9.2.1 h1:4rWNJkj+aPuDFqgieTzNhHBuYaXREh3yaB9NlBerFys= github.com/go-pg/pg/v9 v9.2.1/go.mod h1:fG8qbL+ei4e/fCZLHK+Z+/7b9B+pliZtbpaucG4/YNQ= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= @@ -46,6 +49,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -82,9 +86,16 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -103,6 +114,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= @@ -111,21 +124,32 @@ github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6cz github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc= +github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= +github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -133,26 +157,49 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -160,6 +207,9 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -187,11 +237,14 @@ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -199,4 +252,6 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= +mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= +mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/main.go b/main.go index f2f7f0a..4299df8 100644 --- a/main.go +++ b/main.go @@ -1,143 +1,57 @@ package main import ( - // "fmt" - "net/http" - "github.com/gin-gonic/gin" - models "harshsinghvi/golang-postgres-kubernetes/models" - "harshsinghvi/golang-postgres-kubernetes/database" "log" + "net/http" + "github.com/gin-gonic/gin" "github.com/joho/godotenv" + "harshsinghvi/golang-postgres-kubernetes/database" + "harshsinghvi/golang-postgres-kubernetes/controllers" + "harshsinghvi/golang-postgres-kubernetes/controllers_old" ) - -var TODOS = []models.Todo{ - {ID: "1", Text: "Task 1", Completed: false}, - {ID: "2", Text: "Task 2", Completed: false}, - {ID: "3", Text: "Task 3", Completed: false}, -} - -func getTodos(c *gin.Context) { - id := c.Query("id") - // completed := c.Query("completed") == "true" // TODO: implement this filter - - if id == "" { - c.IndentedJSON(http.StatusOK, TODOS) - return - } - - for _, a := range TODOS { - if a.ID == id { - c.IndentedJSON(http.StatusOK, a) - return - } - } - - c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "not found"}) - +func healthHandler(c *gin.Context) { + c.IndentedJSON(http.StatusOK, gin.H{"message": "OK"}) } - -func postTodos(c *gin.Context) { - var newTodo models.Todo - - // Call BindJSON to bind the received JSON to - if err := c.BindJSON(&newTodo); err != nil { - return - } - - if newTodo.Text == "" { - c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no text"}) - return - } - - for _, a := range TODOS { - if(a.ID == newTodo.ID){ - c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "Duplicate ID"}) - return - } - } - // Add the new album to the slice. - TODOS = append(TODOS, newTodo) - c.IndentedJSON(http.StatusCreated, newTodo) -} - -func updateTodos(c *gin.Context){ - id := c.Param("id") - var updateTodo models.Todo - - // Call BindJSON to bind the received JSON to - if err := c.BindJSON(&updateTodo); err != nil { - return - } - - if updateTodo.ID == "" { - c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no ID"}) - return - } - - for index, a := range TODOS { - if a.ID == id { - if updateTodo.Text != "" { - TODOS[index].Text = updateTodo.Text - } - TODOS[index].Completed = updateTodo.Completed - c.IndentedJSON(http.StatusOK, TODOS[index]) - return - } - } - - c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "invalid ID"}) -} - -func deleteTodos(c *gin.Context){ - id := c.Param("id") - - for index, a := range TODOS { - if a.ID == id{ - TODOS = append(TODOS[:index], TODOS[index+1:]...) - c.IndentedJSON(http.StatusOK, TODOS) - return - } - } - - c.IndentedJSON(http.StatusBadRequest, gin.H{"error": "no ID"}) -} - -func healthHandler(c *gin.Context){ - c.IndentedJSON(http.StatusOK, gin.H {"message": "OK"}) -} -func readinessHandler(c *gin.Context){ +func readinessHandler(c *gin.Context) { if !database.IsDtabaseReady() { - c.IndentedJSON(http.StatusServiceUnavailable, gin.H {"message": "server not ready"}) + c.IndentedJSON(http.StatusServiceUnavailable, gin.H{"message": "server not ready"}) return } - c.IndentedJSON(http.StatusOK, gin.H {"message": "OK"}) + c.IndentedJSON(http.StatusOK, gin.H{"message": "OK"}) } func main() { err := godotenv.Load() if err != nil { - log.Printf("Error loading .env file") + log.Printf("Error loading .env file") } - database.Connect(); - database.CreateTodoTable(); - - router := gin.Default() - router.GET("/v1/todo", getTodos) - router.POST("v1/todo", postTodos) - router.PUT("v1/todo/:id", updateTodos) - router.DELETE("v1/todo/:id", deleteTodos) + database.Connect() + database.CreateTodoTable() + + router := gin.Default() + api := router.Group("/api") + { + v1 := api.Group("/v1") + { + v1.GET("/todo", controllers_old.GetTodos) + v1.POST("/todo", controllers_old.PostTodos) + v1.PUT("/todo/:id", controllers_old.UpdateTodos) + v1.DELETE("/todo/:id", controllers_old.DeleteTodos) + } - router.GET("/v2/todo", database.GetAllTodos) - router.GET("/v2/todos", database.GetAllTodos) - router.GET("/v2/todo/:id", database.GetSingleTodo) - router.POST("v2/todo", database.CreateTodo) - router.PUT("v2/todo/:id", database.EditTodo) - router.DELETE("v2/todo/:id", database.DeleteTodo) - - router.GET("/health", healthHandler) - router.GET("/readiness", readinessHandler) + v2 := api.Group("/v2") + { + v2.GET("/todo", controllers.GetAllTodos) + v2.GET("/todo/:id", controllers.GetSingleTodo) + v2.POST("/todo", controllers.CreateTodo) + v2.PUT("/todo/:id", controllers.EditTodo) + v2.DELETE("/todo/:id", controllers.DeleteTodo) + } + } + router.GET("/health", healthHandler) + router.GET("/readiness", readinessHandler) router.Run(":8080") } From 29dd8a8ead71fae83ac7a29a8a9cacdc546e9d60 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 03:12:41 +0530 Subject: [PATCH 15/22] Update Dockerfile --- .gitignore | 1 + Dockerfile | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d7f611d..74c8e88 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ Temporary Items .env docker-compose/ +__debug_bin* diff --git a/Dockerfile b/Dockerfile index efca79e..4bab49e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,6 @@ # STEP 1 build executable binary ############################ FROM golang:alpine AS builder -LABEL org.opencontainers.image.source="https://github.com/harshsinghvi/golang-postgres-kubernetes" # Install git. # Git is required for fetching the dependencies. RUN apk update && apk add --no-cache 'git=~2' From 2b960d0c478918ae3c6d3d457a6655b8e0563bc4 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 03:42:29 +0530 Subject: [PATCH 16/22] Update README --- README.md | 250 +++++++++++++++++++++++++++--------------------------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index e3f628e..52b10f6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - - - - +- - ghcr.io kubernetes - fargarte exose services @@ -60,130 +60,6 @@ aws eks update-kubeconfig --region ap-south-1 --name cluster kubectl exec --stdin --tty pod/postgres-0 -- /bin/bash ``` -## AUTOSCALE LOGS HPA - -`kubectl get hpa php-apache --watch` - -```text -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 2 19m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 19m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 19m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 20m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m -go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 1 21m -go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m -go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m -go-todo-api-hpa Deployment/go-todo-api 27%/30% 1 10 1 22m -go-todo-api-hpa Deployment/go-todo-api 25%/30% 1 10 1 22m -go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m -go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m -go-todo-api-hpa Deployment/go-todo-api 27%/30% 1 10 1 23m -go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m -go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 1 24m -go-todo-api-hpa Deployment/go-todo-api 37%/30% 1 10 2 24m -go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 2 24m -go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 2 24m -go-todo-api-hpa Deployment/go-todo-api 37%/30% 1 10 2 25m -go-todo-api-hpa Deployment/go-todo-api 29%/30% 1 10 2 25m -go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 2 25m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 26m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 26m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 27m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 29m -go-todo-api-hpa Deployment/go-todo-api 67%/30% 1 10 2 29m -go-todo-api-hpa Deployment/go-todo-api 73%/30% 1 10 4 29m -go-todo-api-hpa Deployment/go-todo-api 75%/30% 1 10 5 29m -go-todo-api-hpa Deployment/go-todo-api 74%/30% 1 10 5 30m -go-todo-api-hpa Deployment/go-todo-api 73%/30% 1 10 5 30m -go-todo-api-hpa Deployment/go-todo-api 72%/30% 1 10 5 30m -go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 5 30m -go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 5 31m -go-todo-api-hpa Deployment/go-todo-api 6%/30% 1 10 5 31m -go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 31m -go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 31m -go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 32m -go-todo-api-hpa Deployment/go-todo-api 28%/30% 1 10 5 32m -go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 5 32m -go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 7 32m -go-todo-api-hpa Deployment/go-todo-api 39%/30% 1 10 7 33m -go-todo-api-hpa Deployment/go-todo-api 43%/30% 1 10 7 33m -go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 7 33m -go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 7 33m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 34m -go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 34m -go-todo-api-hpa Deployment/go-todo-api 7%/30% 1 10 7 34m -go-todo-api-hpa Deployment/go-todo-api 6%/30% 1 10 7 34m -go-todo-api-hpa Deployment/go-todo-api 7%/30% 1 10 7 35m -go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 35m -go-todo-api-hpa Deployment/go-todo-api 32%/30% 1 10 7 35m -go-todo-api-hpa Deployment/go-todo-api 33%/30% 1 10 7 36m -go-todo-api-hpa Deployment/go-todo-api 42%/30% 1 10 7 36m -go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 7 36m -go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 7 36m -go-todo-api-hpa Deployment/go-todo-api 17%/30% 1 10 7 37m -go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 37m -go-todo-api-hpa Deployment/go-todo-api 9%/30% 1 10 7 37m -go-todo-api-hpa Deployment/go-todo-api 9%/30% 1 10 7 37m -go-todo-api-hpa Deployment/go-todo-api 10%/30% 1 10 7 38m -go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 38m -go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 7 38m -go-todo-api-hpa Deployment/go-todo-api 31%/30% 1 10 7 39m -go-todo-api-hpa Deployment/go-todo-api 44%/30% 1 10 7 39m -go-todo-api-hpa Deployment/go-todo-api 45%/30% 1 10 7 39m -go-todo-api-hpa Deployment/go-todo-api 34%/30% 1 10 7 39m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 7 40m -go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 7 40m -go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 40m -go-todo-api-hpa Deployment/go-todo-api 30%/30% 1 10 7 41m -go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 7 41m -go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 7 41m -go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 7 42m -go-todo-api-hpa Deployment/go-todo-api 32%/30% 1 10 7 42m -go-todo-api-hpa Deployment/go-todo-api 31%/30% 1 10 7 42m -go-todo-api-hpa Deployment/go-todo-api 29%/30% 1 10 7 43m -go-todo-api-hpa Deployment/go-todo-api 25%/30% 1 10 7 43m -go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 7 44m -go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 44m -go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 44m -go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 7 44m -go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 45m -go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 45m -go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 45m -go-todo-api-hpa Deployment/go-todo-api 17%/30% 1 10 7 45m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 46m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 46m -go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 7 46m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 46m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 47m -go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 7 47m -go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 47m -go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 47m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 48m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 48m -go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 48m -go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 5 48m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 4 49m -go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 4 49m -go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 4 49m -go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 4 49m -go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 4 50m -go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 3 50m -go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 50m -go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 3 50m -go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 3 51m -go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 3 51m -go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 52m -go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 3 52m -go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 52m -go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 52m -go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 3 53m -go-todo-api-hpa Deployment/go-todo-api 0%/30% 1 10 3 53m -``` - ## GHCR image build and push `https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry` @@ -320,3 +196,127 @@ aws efs create-mount-target \ --subnet-id subnet-0360ff2918bf5fceb \ --security-groups $security_group_id ``` + +## AUTOSCALE LOGS HPA + +`kubectl get hpa --watch` + +```text +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 2 19m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 19m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 19m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 1 20m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 1 20m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 1 21m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 27%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 25%/30% 1 10 1 22m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 27%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 26%/30% 1 10 1 23m +go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 1 24m +go-todo-api-hpa Deployment/go-todo-api 37%/30% 1 10 2 24m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 2 24m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 2 24m +go-todo-api-hpa Deployment/go-todo-api 37%/30% 1 10 2 25m +go-todo-api-hpa Deployment/go-todo-api 29%/30% 1 10 2 25m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 2 25m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 26m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 26m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 27m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 28m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 2 29m +go-todo-api-hpa Deployment/go-todo-api 67%/30% 1 10 2 29m +go-todo-api-hpa Deployment/go-todo-api 73%/30% 1 10 4 29m +go-todo-api-hpa Deployment/go-todo-api 75%/30% 1 10 5 29m +go-todo-api-hpa Deployment/go-todo-api 74%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 73%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 72%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 5 30m +go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 6%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 31m +go-todo-api-hpa Deployment/go-todo-api 3%/30% 1 10 5 32m +go-todo-api-hpa Deployment/go-todo-api 28%/30% 1 10 5 32m +go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 5 32m +go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 7 32m +go-todo-api-hpa Deployment/go-todo-api 39%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 43%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 7 33m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 7%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 6%/30% 1 10 7 34m +go-todo-api-hpa Deployment/go-todo-api 7%/30% 1 10 7 35m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 35m +go-todo-api-hpa Deployment/go-todo-api 32%/30% 1 10 7 35m +go-todo-api-hpa Deployment/go-todo-api 33%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 42%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 7 36m +go-todo-api-hpa Deployment/go-todo-api 17%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 9%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 9%/30% 1 10 7 37m +go-todo-api-hpa Deployment/go-todo-api 10%/30% 1 10 7 38m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 38m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 7 38m +go-todo-api-hpa Deployment/go-todo-api 31%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 44%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 45%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 34%/30% 1 10 7 39m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 7 40m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 7 40m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 40m +go-todo-api-hpa Deployment/go-todo-api 30%/30% 1 10 7 41m +go-todo-api-hpa Deployment/go-todo-api 40%/30% 1 10 7 41m +go-todo-api-hpa Deployment/go-todo-api 38%/30% 1 10 7 41m +go-todo-api-hpa Deployment/go-todo-api 36%/30% 1 10 7 42m +go-todo-api-hpa Deployment/go-todo-api 32%/30% 1 10 7 42m +go-todo-api-hpa Deployment/go-todo-api 31%/30% 1 10 7 42m +go-todo-api-hpa Deployment/go-todo-api 29%/30% 1 10 7 43m +go-todo-api-hpa Deployment/go-todo-api 25%/30% 1 10 7 43m +go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 21%/30% 1 10 7 44m +go-todo-api-hpa Deployment/go-todo-api 19%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 17%/30% 1 10 7 45m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 46m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 14%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 47m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 48m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 7 48m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 7 48m +go-todo-api-hpa Deployment/go-todo-api 13%/30% 1 10 5 48m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 16%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 15%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 4 49m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 4 50m +go-todo-api-hpa Deployment/go-todo-api 18%/30% 1 10 3 50m +go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 50m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 3 50m +go-todo-api-hpa Deployment/go-todo-api 24%/30% 1 10 3 51m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 3 51m +go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 22%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 52m +go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 3 53m +go-todo-api-hpa Deployment/go-todo-api 0%/30% 1 10 3 53m +``` \ No newline at end of file From 582d42bdd3f3564066ea4b4426a3f19aff9fed0d Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 12:02:54 +0530 Subject: [PATCH 17/22] server readiness --- README.md | 6 ++---- database/database.go | 13 ++++++++++--- k8s-deployments/deployment.yml | 9 +++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 52b10f6..d9e411d 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,10 @@ ## commands ```bash - kubectl rollout restart deployment/name # to update image kubectl get ingress # ingress exposed url - -aws eks update-kubeconfig --region ap-south-1 --name cluster kubectl exec --stdin --tty pod/postgres-0 -- /bin/bash +aws eks update-kubeconfig --region ap-south-1 --name cluster ``` ## GHCR image build and push @@ -319,4 +317,4 @@ go-todo-api-hpa Deployment/go-todo-api 23%/30% 1 10 3 go-todo-api-hpa Deployment/go-todo-api 20%/30% 1 10 3 52m go-todo-api-hpa Deployment/go-todo-api 8%/30% 1 10 3 53m go-todo-api-hpa Deployment/go-todo-api 0%/30% 1 10 3 53m -``` \ No newline at end of file +``` diff --git a/database/database.go b/database/database.go index d3fbce4..b8f0734 100644 --- a/database/database.go +++ b/database/database.go @@ -8,11 +8,18 @@ import ( "log" ) -var database_ready = false var Connection *pg.DB func IsDtabaseReady() bool { - return database_ready + ctx := Connection.Context() + var version string + + _, err := Connection.QueryOneContext(ctx, pg.Scan(&version), "SELECT version()") + if err != nil { + log.Printf("Failed to connect to database") + return false + } + return true } func GetDatabase() **pg.DB { @@ -49,7 +56,7 @@ func Connect() *pg.DB { } log.Printf("Connected to db") - database_ready = true + return Connection } diff --git a/k8s-deployments/deployment.yml b/k8s-deployments/deployment.yml index 09a02d4..98f1a79 100644 --- a/k8s-deployments/deployment.yml +++ b/k8s-deployments/deployment.yml @@ -15,6 +15,15 @@ spec: spec: # Spec for the container which will run in the Pod imagePullSecrets: - name: dockerconfigjson-github-com + # initContainers: + # - name: check-db-ready + # image: postgres:latest + # command: ['sh', '-c', + # 'until pg_isready -h $DB_HOST -p $DB_PORT; + # do echo waiting for database; sleep 2; done;'] + # envFrom: + # - secretRef: + # name: app-secret containers: - name: go-todo-api image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest From 6b27af349291f0665422d2104414263fb5094e18 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 13:22:06 +0530 Subject: [PATCH 18/22] Update Update controller to update text field too --- README.md | 3 +-- controllers/controllers.go | 21 +++++++++++++++++++-- docker-compose.yml | 21 ++++++++++++--------- k8s-deployments/deployment.yml | 18 +++++++++--------- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index d9e411d..5f5bb50 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ ```bash kubectl rollout restart deployment/name # to update image kubectl get ingress # ingress exposed url +kubectl port-forward statefulset.apps/postgres 5432:5432 kubectl exec --stdin --tty pod/postgres-0 -- /bin/bash aws eks update-kubeconfig --region ap-south-1 --name cluster ``` @@ -64,9 +65,7 @@ aws eks update-kubeconfig --region ap-south-1 --name cluster ```bash docker buildx build --platform=linux/amd64 -t golang-postgres-kubernetes . - docker tag golang-postgres-kubernetes ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest - docker push ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest ``` diff --git a/controllers/controllers.go b/controllers/controllers.go index c874245..318fcb0 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -92,8 +92,15 @@ func EditTodo(c *gin.Context) { todoId := c.Param("id") var todo models.Todo c.BindJSON(&todo) - completed := todo.Completed - _, err := database.Connection.Model(&models.Todo{}).Set("completed = ?", completed).Where("id = ?", todoId).Update() + + querry := database.Connection.Model(&models.Todo{}).Set("completed = ?", todo.Completed) + + if todo.Text != "" { + querry.Set("text = ?", todo.Text) + } + + res, err := querry.Where("id = ?", todoId).Update() + if err != nil { log.Printf("Error, Reason: %v\n", err) c.JSON(http.StatusInternalServerError, gin.H{ @@ -102,6 +109,16 @@ func EditTodo(c *gin.Context) { }) return } + + if res.RowsAffected() == 0 { + log.Printf("Error while update todo, Reason: \n") + c.JSON(http.StatusNotFound, gin.H{ + "status": http.StatusNotFound, + "message": "Todo not found", + }) + return + } + c.JSON(http.StatusOK, gin.H{ "status": 200, "message": "Todo Edited Successfully", diff --git a/docker-compose.yml b/docker-compose.yml index acc121d..77fdccf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,8 +11,14 @@ services: networks: - fullstack environment: - - PORT=${PORT} - - POSTGRES_URL=postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable + - DB_HOST=${DB_HOST} + - DB_DRIVER=${DB_DRIVER} + - DB_USER=${DB_USER} + - DB_PASSWORD=${DB_PASSWORD} + - DB_NAME=${DB_NAME} + - DB_PORT=${DB_PORT} + - POSTGRES_URL=${POSTGRES_URL} + # - PORT=${PORT} postgres: image: postgres:latest @@ -21,16 +27,13 @@ services: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} - - DATABASE_HOST=${DB_HOST} + - DATABASE_HOST=${DB_HOST} ports: - - '5432:5432' + - 5432:5432 volumes: - - ./docker-compose/postgres:/var/lib/postgresql/data + - ./docker-compose/postgres:/var/lib/postgresql networks: - - fullstack - -volumes: - database_postgres: + - fullstack # Networks to be created to facilitate communication between containers networks: diff --git a/k8s-deployments/deployment.yml b/k8s-deployments/deployment.yml index 98f1a79..64817b4 100644 --- a/k8s-deployments/deployment.yml +++ b/k8s-deployments/deployment.yml @@ -15,15 +15,15 @@ spec: spec: # Spec for the container which will run in the Pod imagePullSecrets: - name: dockerconfigjson-github-com - # initContainers: - # - name: check-db-ready - # image: postgres:latest - # command: ['sh', '-c', - # 'until pg_isready -h $DB_HOST -p $DB_PORT; - # do echo waiting for database; sleep 2; done;'] - # envFrom: - # - secretRef: - # name: app-secret + initContainers: + - name: check-db-ready + image: postgres:latest + command: ['sh', '-c', + 'until pg_isready -h $DB_HOST -p $DB_PORT; + do echo waiting for database; sleep 2; done;'] + envFrom: + - secretRef: + name: app-secret containers: - name: go-todo-api image: ghcr.io/harshsinghvi/golang-postgres-kubernetes:latest From c9a08d702d99a332e597b46a3bb65a64256ea4b4 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 13:59:21 +0530 Subject: [PATCH 19/22] Create indexes --- controllers/controllers.go | 2 +- database/database.go | 10 ++++++++-- models/todo.go | 1 - 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/controllers/controllers.go b/controllers/controllers.go index 318fcb0..96a60dd 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -93,7 +93,7 @@ func EditTodo(c *gin.Context) { var todo models.Todo c.BindJSON(&todo) - querry := database.Connection.Model(&models.Todo{}).Set("completed = ?", todo.Completed) + querry := database.Connection.Model(&models.Todo{}).Set("completed = ?", todo.Completed).Set("updated_at = ?", time.Now()) if todo.Text != "" { querry.Set("text = ?", todo.Text) diff --git a/database/database.go b/database/database.go index b8f0734..764e932 100644 --- a/database/database.go +++ b/database/database.go @@ -13,7 +13,6 @@ var Connection *pg.DB func IsDtabaseReady() bool { ctx := Connection.Context() var version string - _, err := Connection.QueryOneContext(ctx, pg.Scan(&version), "SELECT version()") if err != nil { log.Printf("Failed to connect to database") @@ -71,6 +70,13 @@ func CreateTodoTable() error { log.Printf("Error while creating todo table, Reason: %v\n", createError) return createError } - log.Printf("Todo table created") + + _, err := Connection.Exec(`CREATE UNIQUE INDEX IF NOT EXISTS index_todo ON todos(id, completed, created_at, updated_at);`) + + if err != nil { + log.Printf(err.Error()) + } + + log.Printf("Todo table and indexes created") return nil } diff --git a/models/todo.go b/models/todo.go index 6271184..f70b307 100644 --- a/models/todo.go +++ b/models/todo.go @@ -9,4 +9,3 @@ type Todo struct { CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } - From fca1dc1de15b83afceeac6a763d827f85b6216af Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Fri, 17 Nov 2023 14:42:30 +0530 Subject: [PATCH 20/22] Working docker-compose.yml --- README.md | 4 ++++ docker-compose.yml | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5f5bb50..902c8cf 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,10 @@ kubectl rollout restart deployment/name # to update image kubectl get ingress # ingress exposed url kubectl port-forward statefulset.apps/postgres 5432:5432 kubectl exec --stdin --tty pod/postgres-0 -- /bin/bash +kubectl logs -f pod/go-todo-api-5587558c9b-zhb75 -c check-db-ready + +psql -h localhost -p 5432 -d postgres -U postgres + aws eks update-kubeconfig --region ap-south-1 --name cluster ``` diff --git a/docker-compose.yml b/docker-compose.yml index 77fdccf..2c1fbf7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,11 +7,11 @@ services: - 8080:8080 restart: on-failure depends_on: - - postgres + - postgres networks: - fullstack environment: - - DB_HOST=${DB_HOST} + - DB_HOST=postgres - DB_DRIVER=${DB_DRIVER} - DB_USER=${DB_USER} - DB_PASSWORD=${DB_PASSWORD} @@ -23,17 +23,17 @@ services: postgres: image: postgres:latest container_name: postgres + hostname: postgres environment: - - POSTGRES_USER=${DB_USER} + - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} - - DATABASE_HOST=${DB_HOST} ports: - 5432:5432 volumes: - - ./docker-compose/postgres:/var/lib/postgresql + - ./docker-compose/postgres:/var/lib/postgresql/data networks: - - fullstack + - fullstack # Networks to be created to facilitate communication between containers networks: From 29ddda0c123c3bdded4e1a839973a7d48736844d Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Sat, 18 Nov 2023 11:16:27 +0530 Subject: [PATCH 21/22] Pagination Querry Get all Todos --- README.md | 4 +-- controllers/controllers.go | 44 +++++++++++++++++++++++++------- database/database.go | 2 +- k8s-eks-system/loadgenerator.yml | 4 +-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 902c8cf..0312ba4 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ kubectl rollout restart deployment/name # to update image kubectl get ingress # ingress exposed url kubectl port-forward statefulset.apps/postgres 5432:5432 kubectl exec --stdin --tty pod/postgres-0 -- /bin/bash -kubectl logs -f pod/go-todo-api-5587558c9b-zhb75 -c check-db-ready +kubectl logs -f pod/go-todo-api-5587558c9b-zhb75 -c check-db-ready psql -h localhost -p 5432 -d postgres -U postgres @@ -146,7 +146,6 @@ cidr_range=$(aws ec2 describe-vpcs \ --output text \ --region $AWS_EKS_CLUSTER_REGION) - security_group_id=$(aws ec2 create-security-group \ --group-name MyEfsSecurityGroup \ --description "My EFS security group" \ @@ -165,7 +164,6 @@ file_system_id=$(aws efs create-file-system \ --query 'FileSystemId' \ --output text) - aws ec2 describe-subnets \ --filters "Name=vpc-id,Values=$vpc_id" \ --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \ diff --git a/controllers/controllers.go b/controllers/controllers.go index 96a60dd..be4a28b 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -6,24 +6,43 @@ import ( guuid "github.com/google/uuid" "log" "net/http" + "strconv" "time" "harshsinghvi/golang-postgres-kubernetes/database" "harshsinghvi/golang-postgres-kubernetes/models" ) -// var (connection *pg.DB )// = *database.GetDatabase() - -// init() { -// connection = = *database.GetDatabase() -// } +func GetAllTodos(c *gin.Context) { + var page int + var todos []models.Todo -// connection := *database.GetDatabase() + totalRecords, err := database.Connection.Model(&todos).Count() + if err != nil { + log.Printf("Error while getting all todos, Reason: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) + return + } -func GetAllTodos(c *gin.Context) { + totalPages := totalRecords / 10 + + if c.Query("page") == "" { + page = 1 + } else { + page, _ = strconv.Atoi(c.Query("page")) + if page == -1 { + err = database.Connection.Model(&todos).Order("created_at DESC").Select() + } else { + if page < 1 { + page = 1 + } + err = database.Connection.Model(&todos).Order("created_at DESC").Limit(10).Offset(10 * page).Select() + } + } - var todos []models.Todo - err := database.Connection.Model(&todos).Select() if err != nil { log.Printf("Error while getting all todos, Reason: %v\n", err) c.JSON(http.StatusInternalServerError, gin.H{ @@ -36,6 +55,13 @@ func GetAllTodos(c *gin.Context) { "status": http.StatusOK, "message": "All Todos", "data": todos, + "pagination": gin.H{ + "total_records": totalRecords, + "current_page": page, + "total_pages": totalPages, + "next_page": page + 1, + "prev_page": page - 1, + }, }) } diff --git a/database/database.go b/database/database.go index 764e932..e8c9d44 100644 --- a/database/database.go +++ b/database/database.go @@ -74,7 +74,7 @@ func CreateTodoTable() error { _, err := Connection.Exec(`CREATE UNIQUE INDEX IF NOT EXISTS index_todo ON todos(id, completed, created_at, updated_at);`) if err != nil { - log.Printf(err.Error()) + log.Println(err.Error()) } log.Printf("Todo table and indexes created") diff --git a/k8s-eks-system/loadgenerator.yml b/k8s-eks-system/loadgenerator.yml index 7d6cd30..a5a20f1 100644 --- a/k8s-eks-system/loadgenerator.yml +++ b/k8s-eks-system/loadgenerator.yml @@ -5,7 +5,7 @@ metadata: labels: app: loadgenerator spec: - replicas: 3 + replicas: 50 selector: matchLabels: app: loadgenerator @@ -22,4 +22,4 @@ spec: command: - /bin/sh - -c - - "while true; do wget -q -O- http://golang-todo-api-service:8080/todos; done" \ No newline at end of file + - "while true; do wget -q -O- http://golang-todo-api-service:8080/api/v2/todo; done" \ No newline at end of file From 6b5a9a3d60651ba98aab994b65e8d2337d00dc35 Mon Sep 17 00:00:00 2001 From: Harsh Singhvi Date: Sat, 18 Nov 2023 13:56:53 +0530 Subject: [PATCH 22/22] Search Functionality and restructure --- controllers/controllers.go | 104 ++++++++++++------------------------- models/pagination.go | 58 +++++++++++++++++++++ utils/error.go | 15 ++++++ utils/utils.go | 6 +-- 4 files changed, 110 insertions(+), 73 deletions(-) create mode 100644 models/pagination.go create mode 100644 utils/error.go diff --git a/controllers/controllers.go b/controllers/controllers.go index be4a28b..25317c5 100644 --- a/controllers/controllers.go +++ b/controllers/controllers.go @@ -1,80 +1,59 @@ package controllers import ( + "fmt" "github.com/gin-gonic/gin" - // "github.com/go-pg/pg/v9" guuid "github.com/google/uuid" + "harshsinghvi/golang-postgres-kubernetes/database" + "harshsinghvi/golang-postgres-kubernetes/models" + "harshsinghvi/golang-postgres-kubernetes/utils" "log" "net/http" - "strconv" "time" - - "harshsinghvi/golang-postgres-kubernetes/database" - "harshsinghvi/golang-postgres-kubernetes/models" ) func GetAllTodos(c *gin.Context) { - var page int + var pag models.Pagination + var err error + var todos []models.Todo + var searchString = c.Query("search") + var pageString = c.Query("page") + pag.ParseString(pageString) - totalRecords, err := database.Connection.Model(&todos).Count() - if err != nil { - log.Printf("Error while getting all todos, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) + querry := database.Connection.Model(&todos).Order("created_at DESC") + + if searchString != "" { + querry = querry.Where(fmt.Sprintf("text like '%%%s%%'", searchString)) + } + + if pag.TotalRecords, err = querry.Count(); err != nil { + utils.InternalServerError(c, "Error while getting all todos, Reason:", err) return } - totalPages := totalRecords / 10 - - if c.Query("page") == "" { - page = 1 - } else { - page, _ = strconv.Atoi(c.Query("page")) - if page == -1 { - err = database.Connection.Model(&todos).Order("created_at DESC").Select() - } else { - if page < 1 { - page = 1 - } - err = database.Connection.Model(&todos).Order("created_at DESC").Limit(10).Offset(10 * page).Select() - } + if pag.CurrentPage != -1 { + querry = querry.Limit(10).Offset(10 * (pag.CurrentPage)) } - if err != nil { - log.Printf("Error while getting all todos, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) + if err := querry.Select(); err != nil { + utils.InternalServerError(c, "Error while getting all todos, Reason:", err) return } + c.JSON(http.StatusOK, gin.H{ - "status": http.StatusOK, - "message": "All Todos", - "data": todos, - "pagination": gin.H{ - "total_records": totalRecords, - "current_page": page, - "total_pages": totalPages, - "next_page": page + 1, - "prev_page": page - 1, - }, + "status": http.StatusOK, + "message": "All Todos", + "data": todos, + "pagination": pag.Validate(), }) } func GetSingleTodo(c *gin.Context) { todoId := c.Param("id") todo := &models.Todo{ID: todoId} - err := database.Connection.Select(todo) - if err != nil { - log.Printf("Error while getting a single todo, Reason: %v\n", err) - c.JSON(http.StatusNotFound, gin.H{ - "status": http.StatusNotFound, - "message": "Todo not found", - }) + if err := database.Connection.Select(todo); err != nil { + utils.InternalServerError(c, "Error while getting a single todo, Reason:", err) return } c.JSON(http.StatusOK, gin.H{ @@ -100,11 +79,7 @@ func CreateTodo(c *gin.Context) { }) if insertError != nil { - log.Printf("Error while inserting new todo into db, Reason: %v\n", insertError) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) + utils.InternalServerError(c, "Error while inserting new todo into db, Reason:", insertError) return } @@ -120,20 +95,14 @@ func EditTodo(c *gin.Context) { c.BindJSON(&todo) querry := database.Connection.Model(&models.Todo{}).Set("completed = ?", todo.Completed).Set("updated_at = ?", time.Now()) - if todo.Text != "" { - querry.Set("text = ?", todo.Text) + querry = querry.Set("text = ?", todo.Text) } res, err := querry.Where("id = ?", todoId).Update() if err != nil { - log.Printf("Error, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": 500, - "message": "Something went wrong", - }) - return + utils.InternalServerError(c, "Error while editing todo, Reason:", err) } if res.RowsAffected() == 0 { @@ -154,13 +123,8 @@ func EditTodo(c *gin.Context) { func DeleteTodo(c *gin.Context) { todoId := c.Param("id") todo := &models.Todo{ID: todoId} - err := database.Connection.Delete(todo) - if err != nil { - log.Printf("Error while deleting a single todo, Reason: %v\n", err) - c.JSON(http.StatusInternalServerError, gin.H{ - "status": http.StatusInternalServerError, - "message": "Something went wrong", - }) + if err := database.Connection.Delete(todo); err != nil { + utils.InternalServerError(c, "Error while deleting a single todo, Reason:", err) return } c.JSON(http.StatusOK, gin.H{ diff --git a/models/pagination.go b/models/pagination.go new file mode 100644 index 0000000..b2c151a --- /dev/null +++ b/models/pagination.go @@ -0,0 +1,58 @@ +package models + +import "strconv" + +type Pagination struct { + TotalRecords int `json:"total_records"` + CurrentPage int `json:"current_page"` + TotalPages int `json:"total_pages"` + NextPage int `json:"next_page"` + PrevPage int `json:"prev_page"` +} + +func (pag *Pagination) Validate() *Pagination { + pag.Set(pag.CurrentPage, pag.TotalRecords) + return pag +} + +func (pag *Pagination) Set(current int, totalRec int) *Pagination { + pag.TotalRecords = totalRec + + if pag.TotalPages = pag.TotalRecords / 10; pag.TotalRecords%10 == 0 { + pag.TotalPages = pag.TotalPages - 1 + } + + if current <= 0 { + pag.PrevPage = 0 + } else { + pag.PrevPage = current - 1 + } + + if current >= pag.TotalPages { + pag.NextPage = pag.TotalPages + } else { + pag.NextPage = current + 1 + } + + pag.CurrentPage = current + return pag +} + +func (pag *Pagination) ParseString(pageString string) { + pag.CurrentPage = 0 + + if pageString == "" { + return + } + + pag.CurrentPage, _ = strconv.Atoi(pageString) + + if pag.CurrentPage == -1 { + return + } + + if pag.CurrentPage < 0 { + pag.CurrentPage = 0 + return + } +} diff --git a/utils/error.go b/utils/error.go new file mode 100644 index 0000000..37b9e02 --- /dev/null +++ b/utils/error.go @@ -0,0 +1,15 @@ +package utils + +import ( + "github.com/gin-gonic/gin" + "log" + "net/http" +) + +func InternalServerError(c *gin.Context, msg string, err error) { + log.Printf("%s %v\n", msg, err) + c.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Something went wrong", + }) +} diff --git a/utils/utils.go b/utils/utils.go index 3ee1f7f..7505e09 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,9 +5,9 @@ import ( ) func GetEnv(varNameString string, defaultValue string) string { - var varValue string; + var varValue string if varValue = os.Getenv(varNameString); varNameString == "" { varValue = defaultValue } - return varValue; -} \ No newline at end of file + return varValue +}