diff --git a/.gitignore b/.gitignore index c40ba19..52fc50a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin .vscode debug +vendor diff --git a/Makefile b/Makefile index 9a253b7..0f3331b 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,7 @@ PROJECT_ROOT := github.com/infobloxopen/atlas-contacts-app BUILD_PATH := bin DOCKERFILE_PATH := $(CURDIR)/docker -USERNAME := $(USER) -GIT_COMMIT := $(shell git describe --dirty=-unsupported --always || echo pre-commit) -IMAGE_VERSION ?= v1.0 +IMAGE_VERSION ?= latest SERVER_BINARY := $(BUILD_PATH)/server SERVER_PATH := $(PROJECT_ROOT)/cmd/server @@ -92,13 +90,11 @@ vendor-update: $(BUILDER) dep ensure .PHONY: image -image: - docker build -f docker/Dockerfile.contacts-server -t infoblox/contacts-server:v1.0 . - docker build -f docker/Dockerfile.contacts-gateway -t infoblox/contacts-gateway:v1.0 . +image: server gateway .PHONY: image-clean image-clean: - docker rmi -f infoblox/contacts-server:v1.0 infoblox/contacts-gateway:v1.0 + docker rmi -f $(SERVER_IMAGE) $(GATEWAY_IMAGE) .PHONY: up up: @@ -107,3 +103,11 @@ up: .PHONY: down down: kubectl delete -f kube/kube.yaml + +.PHONY: nginx-up +nginx-up: + kubectl apply -f kube/nginx.yaml + +.PHONY: nginx-down +nginx-down: + kubectl delete -f kube/nginx.yaml \ No newline at end of file diff --git a/README.md b/README.md index fed1dae..43bc8e9 100644 --- a/README.md +++ b/README.md @@ -61,38 +61,64 @@ curl http://localhost:8080/atlas-contacts-app/v1/contacts -d '{"first_name": "Bo ``` sh curl http://localhost:8080/atlas-contacts-app/v1/contacts?_filter='first_name=="Mike"' +``` #### Local Kubernetes setup -Open a seperate terminal session where execute `eval $(minikube docker-env)`. This is needed to make these images available for local kubernetes without pushing them to global repo. +##### Prerequisites + +Make sure nginx is deployed in you K8s. Otherwise you can deploy it using + +``` sh +make nginx-up +``` + +or by running -Then: +``` sh +kubectl apply -f kube/nginx.yaml +``` + +If you launching atlas-contacts-app for the first time you need to create `contacts` namespace for it in Kubernetes. This can be done by running + +``` sh +kubectl apply -f kube/ns.yaml +``` + +or + +``` sh +kubectl create ns contacts +``` + +##### Deployment + +To deploy atlas-contacts-app use ``` sh -make image make up ``` -To shutdown and cleanup: +or as alternative you can run ``` sh -make down -make image-clean -rm -rf bin +kubectl apply -f kube/kube.yaml ``` -#### Try local Kubernetes atlas-contacts-app +##### Usage + +Try it out by executing following curl commangs: ``` sh -curl http://$(minikube ip):31500/atlas-contacts-app/v1/contacts -d '{"first_name": "Mike", "email_address": "mike@gmail.com"}' +curl https://minikube/atlas-contacts-app/v1/contacts -d '{"first_name": "Mike", "email_address": "mike@gmail.com"}' ``` ``` sh -curl http://$(minikube ip):31500/atlas-contacts-app/v1/contacts -d '{"first_name": "Bob", "email_address": "john@gmail.com"}' +curl https://minikube/atlas-contacts-app/v1/contacts -d '{"first_name": "Bob", "email_address": "john@gmail.com"}' ``` ``` sh -curl http://$(minikube ip):31500/atlas-contacts-app/v1/contacts?_filter='first_name=="Mike"' +curl https://minikube/atlas-contacts-app/v1/contacts?_filter='first_name=="Mike"' ``` ## Deployment diff --git a/deploy/contacts.yaml b/deploy/contacts.yaml deleted file mode 100644 index 30aace8..0000000 --- a/deploy/contacts.yaml +++ /dev/null @@ -1,84 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: contacts-api -spec: - selector: - app: contacts - component: api - type: ClusterIP - ports: - - name: grpc - port: 9091 - protocol: TCP ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: contacts-api -spec: - replicas: 1 - selector: - matchLabels: - app: contacts - component: api - template: - metadata: - labels: - app: contacts - component: api - spec: - containers: - - args: - - -dsn - - api:mypassword@tcp(mysql.db:3306)/contacts?charset=utf8&parseTime=True - image: atlas-contacts-app:latest - imagePullPolicy: Always - name: contacts-api - ports: - - containerPort: 9091 - name: grpc - protocol: TCP ---- -apiVersion: v1 -kind: Service -metadata: - name: contacts-rest -spec: - selector: - app: contacts - component: gateway - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: 8080 - protocol: TCP ---- -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: contacts-gateway -spec: - replicas: 1 - selector: - matchLabels: - app: contacts - component: gateway - template: - metadata: - labels: - app: contacts - component: gateway - spec: - containers: - - args: - - -contacts - - contacts-api:9091 - image: atlas-contacts-app-gateway:latest - imagePullPolicy: Always - name: contacts-gateway - ports: - - containerPort: 8080 - name: http - protocol: TCP diff --git a/kube/kube.yaml b/kube/kube.yaml index 2ac07f4..c5e3fe3 100644 --- a/kube/kube.yaml +++ b/kube/kube.yaml @@ -24,7 +24,7 @@ spec: rules: - http: paths: - - path: /contacts + - path: /atlas-contacts-app backend: serviceName: contacts-app servicePort: 8080 @@ -53,7 +53,7 @@ spec: - "0.0.0.0:8088" - "-shealth" - "0.0.0.0:8089" - image: infoblox/contacts-gateway:v1.0 + image: infoblox/contacts-gateway:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8080 @@ -84,7 +84,7 @@ spec: # note that authz also needs to be running in order to authorize # requests to the contacts-app # - "-authz=pdpserver.authz:5555" - image: infoblox/contacts-server:v1.0 + image: infoblox/contacts-server:latest imagePullPolicy: IfNotPresent ports: - containerPort: 9091 diff --git a/kube/nginx.yaml b/kube/nginx.yaml new file mode 100644 index 0000000..afea22b --- /dev/null +++ b/kube/nginx.yaml @@ -0,0 +1,112 @@ +kind: Service +apiVersion: v1 +metadata: + name: nginx-default-backend + labels: + k8s-addon: ingress-nginx.addons.k8s.io +spec: + ports: + - port: 80 + targetPort: http + selector: + app: nginx-default-backend +--- +kind: Deployment +apiVersion: extensions/v1beta1 +metadata: + name: nginx-default-backend + labels: + k8s-addon: ingress-nginx.addons.k8s.io +spec: + replicas: 1 + template: + metadata: + labels: + k8s-addon: ingress-nginx.addons.k8s.io + app: nginx-default-backend + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: default-http-backend + image: gcr.io/google_containers/defaultbackend:1.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi + ports: + - name: http + containerPort: 8080 + protocol: TCP +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: ingress-nginx + labels: + k8s-addon: ingress-nginx.addons.k8s.io +data: + use-proxy-protocol: "false" +--- +kind: Deployment +apiVersion: extensions/v1beta1 +metadata: + name: ingress-nginx + labels: + k8s-addon: ingress-nginx.addons.k8s.io +spec: + replicas: 1 + template: + metadata: + labels: + app: ingress-nginx + k8s-addon: ingress-nginx.addons.k8s.io + spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + terminationGracePeriodSeconds: 60 + containers: + - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.14 + name: ingress-nginx + imagePullPolicy: Always + ports: + - name: http + containerPort: 80 + protocol: TCP + - name: https + containerPort: 443 + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 3 + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + args: + - /nginx-ingress-controller + - --default-backend-service=$(POD_NAMESPACE)/nginx-default-backend diff --git a/kube/ns.yaml b/kube/ns.yaml new file mode 100644 index 0000000..898f209 --- /dev/null +++ b/kube/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: contacts diff --git a/pb/contacts/contacts.pb.gorm.go b/pb/contacts/contacts.pb.gorm.go index b5a6436..1e92b27 100644 --- a/pb/contacts/contacts.pb.gorm.go +++ b/pb/contacts/contacts.pb.gorm.go @@ -23,9 +23,10 @@ package contacts import context "context" import errors "errors" + import gorm "github.com/jinzhu/gorm" import ops "github.com/infobloxopen/atlas-app-toolkit/op/gorm" -import proto "github.com/gogo/protobuf/proto" + import fmt "fmt" import math "math" import _ "github.com/golang/protobuf/ptypes/empty" @@ -34,13 +35,12 @@ import _ "github.com/lyft/protoc-gen-validate/validate" import _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" // Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // ContactORM no comment was provided for message type type ContactORM struct { - ID uint64 + Id uint64 FirstName string MiddleName string LastName string @@ -56,7 +56,7 @@ func (ContactORM) TableName() string { func ConvertContactToORM(from Contact) (ContactORM, error) { to := ContactORM{} var err error - to.ID = from.Id + to.Id = from.Id to.FirstName = from.FirstName to.MiddleName = from.MiddleName to.LastName = from.LastName @@ -68,7 +68,7 @@ func ConvertContactToORM(from Contact) (ContactORM, error) { func ConvertContactFromORM(from ContactORM) (Contact, error) { to := Contact{} var err error - to.Id = from.ID + to.Id = from.Id to.FirstName = from.FirstName to.MiddleName = from.MiddleName to.LastName = from.LastName @@ -168,15 +168,12 @@ func DefaultStrictUpdateContact(ctx context.Context, in *Contact, db *gorm.DB) ( if err != nil { return nil, err } - tx := db.Begin() - if err = tx.Save(&ormObj).Error; err != nil { - tx.Rollback() + if err = db.Save(&ormObj).Error; err != nil { return nil, err } pbResponse, err := ConvertContactFromORM(ormObj) if err != nil { return nil, err } - tx.Commit() return &pbResponse, nil }