From a769ffacf283f351ed9b2651d3259e4472a0aa3b Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:23:20 +0000 Subject: [PATCH 1/7] added version page for testing --- .github/workflows/Push-Docker-Azure.yml | 2 +- todo_app/app.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Push-Docker-Azure.yml b/.github/workflows/Push-Docker-Azure.yml index 2145bfb..e5eeaa4 100644 --- a/.github/workflows/Push-Docker-Azure.yml +++ b/.github/workflows/Push-Docker-Azure.yml @@ -35,7 +35,7 @@ jobs: name: Push to DockerHub runs-on: ubuntu-latest needs: build - if: github.ref == 'refs/heads/main' + #if: github.ref == 'refs/heads/main' steps: - name: Checkout uses: actions/checkout@v3 diff --git a/todo_app/app.py b/todo_app/app.py index a5d6f1e..3278c7d 100644 --- a/todo_app/app.py +++ b/todo_app/app.py @@ -97,6 +97,10 @@ def make_complete(id): complete_item(id) app.logger.info(f'Task completed. TaskID {id} Userid: {current_user.id}') return redirect('/') + + @app.route ('/version') + def version(): + return 'module-14 30.12.12' @app.route ('/AccessDenied') From 09b19d95b7fe6c6db547840ba9546a824220cf42 Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:32:25 +0000 Subject: [PATCH 2/7] deployment test --- todo_app/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/todo_app/app.py b/todo_app/app.py index 3278c7d..a417b0f 100644 --- a/todo_app/app.py +++ b/todo_app/app.py @@ -100,7 +100,7 @@ def make_complete(id): @app.route ('/version') def version(): - return 'module-14 30.12.12' + return 'module-14 30.12.12.2' @app.route ('/AccessDenied') From f318377043f85c95ad2288c20a69a544a3aece8e Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Wed, 4 Jan 2023 09:16:08 +0000 Subject: [PATCH 3/7] working k8s/minik8 deployments - needs envs added --- .github/workflows/Push-Docker-Azure.yml | 2 +- deployment.yaml | 36 +++++++++++++++++++++++++ service.yaml | 13 +++++++++ todo_app/app.py | 4 +-- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 deployment.yaml create mode 100644 service.yaml diff --git a/.github/workflows/Push-Docker-Azure.yml b/.github/workflows/Push-Docker-Azure.yml index e5eeaa4..2145bfb 100644 --- a/.github/workflows/Push-Docker-Azure.yml +++ b/.github/workflows/Push-Docker-Azure.yml @@ -35,7 +35,7 @@ jobs: name: Push to DockerHub runs-on: ubuntu-latest needs: build - #if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' steps: - name: Checkout uses: actions/checkout@v3 diff --git a/deployment.yaml b/deployment.yaml new file mode 100644 index 0000000..1dd2c96 --- /dev/null +++ b/deployment.yaml @@ -0,0 +1,36 @@ +# deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: todo-app +spec: + selector: + matchLabels: + app: todo-app + replicas: 1 + template: + metadata: + labels: + app: todo-app + spec: + containers: + - name: todo-app + image: todo-app:minikube + env: + - name: FLASK_APP + value: todo_app/app + - name: FLASK_ENV + value: development + - name: SECRET_KEY + value: ssssssdsdsdw + - name: LOGGLY_TOKEN + value: 6750b0ff-0e89-4f97-842a-b3d9d47c789e + - name: PORT + value: '5000' + - name: CLIENT_ID + value: 3c0ccb0936a4787ac81e + - name: CLIENT_SECRET + value: 8d39d1e5fdb67d1fcff70ea43fe8db242452dccb + imagePullPolicy: Never + ports: + - containerPort: 5000 \ No newline at end of file diff --git a/service.yaml b/service.yaml new file mode 100644 index 0000000..c05b7ec --- /dev/null +++ b/service.yaml @@ -0,0 +1,13 @@ +# service.yaml +kind: Service +apiVersion: v1 +metadata: + name: todo-app +spec: + type: NodePort + selector: + app: todo-app + ports: + - protocol: TCP + port: 5000 + targetPort: 5000 \ No newline at end of file diff --git a/todo_app/app.py b/todo_app/app.py index a417b0f..5f99475 100644 --- a/todo_app/app.py +++ b/todo_app/app.py @@ -20,10 +20,10 @@ logger = logging.getLogger(__name__) -github_oauth_uri = os.getenv('GITHUB_OAUTH_URL') +github_oauth_uri = 'https://github.com/login/oauth/authorize' client_id = os.getenv('CLIENT_ID') client_secret = os.getenv('CLIENT_SECRET') -redirect_uri = os.getenv('REDIRECT_URI') +redirect_uri = 'http://127.0.0.1:5000/login/callback' token_url = 'https://github.com/login/oauth/access_token' administrators = ['94004061'] # list of admin userIds. hardcoded for demo/testing purposes. From 3a92ff18c7a2882fec62cd1de67e17d0689cec00 Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:16:03 +0000 Subject: [PATCH 4/7] moved database variables into code not envvar --- todo_app/data/database_items.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/todo_app/data/database_items.py b/todo_app/data/database_items.py index 6ac3362..ae5c2d2 100644 --- a/todo_app/data/database_items.py +++ b/todo_app/data/database_items.py @@ -10,6 +10,10 @@ from logging import Formatter from loggly.handlers import HTTPSHandler +client = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) +database = client['todo_app'] +collection = database['items'] + logger = logging.getLogger(__name__) if os.getenv('LOGGLY_TOKEN') is not None: handler = HTTPSHandler(f"https://logs-01.loggly.com/inputs/{os.getenv('LOGGLY_TOKEN')}/tag/todo-app") @@ -17,9 +21,7 @@ logger.addHandler(handler) def get_items(): - client = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) - database = client[os.getenv('DATABASE')] - collection = database[os.getenv('COLLECTION')] + logger.debug(f'database name : {database}') items = [] database_items = collection.find() for item in database_items: @@ -28,14 +30,8 @@ def get_items(): return items def add_item(title): - client = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) - database = client[os.getenv('DATABASE')] - collection = database[os.getenv('COLLECTION')] collection.insert_one({'name':title,'status':'To Do','date_modified':datetime.now()}) def complete_item(_id): - client = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) - database = client[os.getenv('DATABASE')] - collection = database[os.getenv('COLLECTION')] collection.update_one({'_id': ObjectId(_id)}, {"$set": {'status':'Done', 'date_modified':datetime.now()}}) \ No newline at end of file From abfb7e55de0a4e5adb3c95bdceab5f3260856603 Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:12:50 +0000 Subject: [PATCH 5/7] call mongodb via function not vars - fixes tests --- todo_app/data/database_items.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/todo_app/data/database_items.py b/todo_app/data/database_items.py index ae5c2d2..458985a 100644 --- a/todo_app/data/database_items.py +++ b/todo_app/data/database_items.py @@ -10,9 +10,8 @@ from logging import Formatter from loggly.handlers import HTTPSHandler -client = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) -database = client['todo_app'] -collection = database['items'] + + logger = logging.getLogger(__name__) if os.getenv('LOGGLY_TOKEN') is not None: @@ -20,8 +19,15 @@ handler.setFormatter(Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")) logger.addHandler(handler) +def get_collection(): + client = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) + database = client['todo_app'] + collection = database['items'] + return collection + def get_items(): - logger.debug(f'database name : {database}') + collection=get_collection() + logger.debug(f'database name : {collection}') items = [] database_items = collection.find() for item in database_items: @@ -29,9 +35,11 @@ def get_items(): logger.debug(f"{len(items)} individual items collected from {collection.count_documents({})} total database records:## Item count and record count should match ##") return items -def add_item(title): +def add_item(title): + collection=get_collection() collection.insert_one({'name':title,'status':'To Do','date_modified':datetime.now()}) def complete_item(_id): + collection=get_collection() collection.update_one({'_id': ObjectId(_id)}, {"$set": {'status':'Done', 'date_modified':datetime.now()}}) \ No newline at end of file From c8240976c517b9eddcedcb12ed2f656d1ddf24ef Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Wed, 4 Jan 2023 16:34:05 +0000 Subject: [PATCH 6/7] pushed secrets to K8s Secrets file. (ignord) --- .gitignore | 3 +++ deployment.yaml | 35 ++++++++++++++++++++++++----------- todo_app/test_pytests.py | 4 ++-- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 6036206..b66239f 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,6 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc + +#k8s +secrets.yaml diff --git a/deployment.yaml b/deployment.yaml index 1dd2c96..3706c5e 100644 --- a/deployment.yaml +++ b/deployment.yaml @@ -15,22 +15,35 @@ spec: spec: containers: - name: todo-app - image: todo-app:minikube + image: todo-app:minikube.1 env: - - name: FLASK_APP - value: todo_app/app - - name: FLASK_ENV - value: development + - name: CLIENT_ID + valueFrom: + secretKeyRef: + name: my-secrets + key: CLIENT_ID + - name: CLIENT_SECRET + valueFrom: + secretKeyRef: + name: secrets + key: CLIENT_SECRET - name: SECRET_KEY - value: ssssssdsdsdw + valueFrom: + secretKeyRef: + name: secrets + key: SECRET_KEY + - name: CONNECTION_STRING + valueFrom: + secretKeyRef: + name: secrets + key: CONNECTION_STRING - name: LOGGLY_TOKEN - value: 6750b0ff-0e89-4f97-842a-b3d9d47c789e + valueFrom: + secretKeyRef: + name: secrets + key: LOGGLY_TOKEN - name: PORT value: '5000' - - name: CLIENT_ID - value: 3c0ccb0936a4787ac81e - - name: CLIENT_SECRET - value: 8d39d1e5fdb67d1fcff70ea43fe8db242452dccb imagePullPolicy: Never ports: - containerPort: 5000 \ No newline at end of file diff --git a/todo_app/test_pytests.py b/todo_app/test_pytests.py index 950c154..8aaa785 100644 --- a/todo_app/test_pytests.py +++ b/todo_app/test_pytests.py @@ -19,8 +19,8 @@ def client(): load_dotenv(file_path, override=True) with mongomock.patch(servers=(('fakemongo.com', 27017),)): mongoclient = pymongo.MongoClient(os.getenv('CONNECTION_STRING')) - db = mongoclient[os.getenv('DATABASE')] - collection = db[os.getenv('COLLECTION')] + db = mongoclient['todo_app'] + collection = db['items'] collection.insert_one({'name': 'test item #222', 'status': 'To Do', 'date_modified' : datetime.now()}) test_app = app.create_app() test_app.config['LOGIN_DISABLED'] = True From ecdb69f100f6b2d50eaf0558c29e2cfe668e596c Mon Sep 17 00:00:00 2001 From: Ian B <94004061+Iabo77@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:04:59 +0000 Subject: [PATCH 7/7] readme update for submission --- README.md | 31 +++++++++++++++++++++++++++++++ secrets_.yaml | 13 +++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 secrets_.yaml diff --git a/README.md b/README.md index e307c98..b28ec31 100644 --- a/README.md +++ b/README.md @@ -130,4 +130,35 @@ LOG_LEVEL is set as an environmental Variable and can be edited to the below val * WARNING * ERROR + + +# MiniKube Set up + To configure a local minikube deployment of the todo-app. Assuming Docker desktop and Minikube are set up locally. + + ### secret.yaml base format +there is a secrets_.yaml file supplied with the code - enter required values as specified and rename to secrets.yaml + +### Build base Docker Image +`docker build --target production --tag todo-app:minikube.1 .` + +## Kubernetes/Minikube Deployment + Load docker image to minikube cache +`minikube image load todo-app:minikube.1` +Start the deployments of services and files +`kubectl apply -f secrets.yaml` +`kubectl apply -f deployment.yaml` +`kubectl apply -f service.yaml` + +start port forwarding of local ports to container +`kubectl port-forward service/todo-app 5000:5000` + +The todoapp web site should now be accessible on localhost:5000 running from local minikube cluster + + + + + + + + diff --git a/secrets_.yaml b/secrets_.yaml new file mode 100644 index 0000000..0e80ac2 --- /dev/null +++ b/secrets_.yaml @@ -0,0 +1,13 @@ +#unpopulated secrets.yaml file. Populate and rename to secrets.yaml before deploying to minikube + +apiVersion: v1 +kind: Secret +metadata: + name: secrets +type: Opaque +data: + CLIENT_ID: + CLIENT_SECRET: + SECRET_KEY: + CONNECTION_STRING: + #LOGGLY_TOKEN: # optional for external logging to loggly \ No newline at end of file