From 047322f1a56ee033bbf5af1724ccab4fa1eb4efd Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Fri, 8 Mar 2019 11:56:07 +0100 Subject: [PATCH 1/9] Added bash version of the Helm deploy script --- k8s/helm/deploy-all.sh | 208 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100755 k8s/helm/deploy-all.sh diff --git a/k8s/helm/deploy-all.sh b/k8s/helm/deploy-all.sh new file mode 100755 index 000000000..adfb111f3 --- /dev/null +++ b/k8s/helm/deploy-all.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env bash + +# http://redsymbol.net/articles/unofficial-bash-strict-mode +set -euo pipefail + +usage() +{ + cat < + The name of the AKS cluster. Required when the registry (using the -r parameter) is set to "aks". + --aks-rg + The resource group for the AKS cluster. Required when the registry (using the -r parameter) is set to "aks". + -b | --build-solution + Force a solution build before deployment (default: false). + -d | --dns + Specifies the external DNS/ IP address of the Kubernetes cluster. + When --use-local-k8s is specified the external DNS is automatically set to localhost. + -h | --help + Displays this help text and exits the script. + -n | --app-name + Specifies the name of the application (default: eshop). + -p | --docker-password + The Docker password used to logon to the custom registry, supplied using the -r parameter. + -r | --registry + Specifies the container registry to use (required), e.g. myregistry.azurecr.io. + --skip-clean + Do not clean the Kubernetes cluster (default is to clean the cluster). + --skip-image-build + Do not build images (default is to build all images). + --skip-image-push + Do not upload images to the container registry (just run the Kubernetes deployment portion). + Default is to push the images to the container registry. + --skip-infrastructure + Do not deploy infrastructure resources (like sql-data, no-sql or redis). + This is useful for production environments where infrastructure is hosted outside the Kubernetes cluster. + -t | --tag + The tag used for the newly created docker images. Default: newly created, date-based timestamp, with 1-minute resolution. + -u | --docker-user + The Docker username used to logon to the custom registry, supplied using the -r parameter. + --use-local-k8s + Deploy to a locally installed Kubernetes (default: false). + +It is assumed that the Kubernetes cluster has been granted access to the container registry. +If using AKS and ACR see link for more info: +https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-aks + +WARNING! THE SCRIPT WILL COMPLETELY DESTROY ALL DEPLOYMENTS AND SERVICES VISIBLE +FROM THE CURRENT CONFIGURATION CONTEXT. +It is recommended that you create a separate namespace and confguration context +for the $app_name application, to isolate it from other applications on the cluster. +For more information see https://kubernetes.io/docs/tasks/administer-cluster/namespaces/ +You can use namespace.yaml file (in the same directory) to create the namespace. + +END +} + +app_name='eshop' +aks_name='' +aks_rg='' +build_images='yes' +clean='yes' +build_solution='' +container_registry='' +docker_password='' +docker_username='' +dns='' +image_tag=$(date '+%Y%m%d%H%M') +push_images='yes' +skip_infrastructure='' +use_local_k8s='' + +while [[ $# -gt 0 ]]; do + case "$1" in + --aks-name ) + aks_name="$2"; shift 2;; + --aks-rg ) + aks_rg="$2"; shift 2;; + -b | --build-solution ) + build_solution='yes'; shift ;; + -d | --dns ) + dns="$2"; shift 2;; + -h | --help ) + usage; exit 1 ;; + -n | --app-name ) + app_name="$2"; shift 2;; + -p | --docker-password ) + docker_password="$2"; shift;; + -r | --registry ) + container_registry="$2"; shift 2;; + --skip-clean ) + clean=''; shift ;; + --skip-image-build ) + build_images=''; shift ;; + --skip-image-push ) + push_images=''; shift ;; + --skip-infrastructure ) + skip_infrastructure='yes'; shift ;; + -t | --tag ) + image_tag="$2"; shift 2;; + -u | --docker-username ) + docker_username="$2"; shift 2;; + --use-local-k8s ) + use_local_k8s=''; shift ;; + *) + echo "Unknown option $1" + usage; exit 2 ;; + esac +done + +if [[ $build_solution ]]; then + echo "#################### Building $app_name solution ####################" + dotnet publish -o obj/Docker/publish ../../winnersworkout-backend.sln +fi + +export TAG=$image_tag + +if [[ $build_images ]]; then + echo "#################### Building the $app_name Docker images ####################" + docker-compose -p .. -f ../../docker-compose.yml build + + # Remove temporary images + docker rmi $(docker images -qf "dangling=true") +fi + +if [[ $push_images ]]; then + echo "#################### Pushing images to the container registry ####################" + services=(basket.api catalog.api identity.api ordering.api marketing.api payment.api locations.api webmvc webspa webstatus) + + for service in "${services[@]}" + do + echo "Pushing image for service $service..." + docker tag "eshop/$service:$image_tag" "$container_registry/$service:$image_tag" + docker push "$container_registry/$service:$image_tag" + done +fi + +ingress_values_file="ingress_values.yaml" + +if [[ $use_local_k8s ]]; then + ingress_values_file="ingress_values_dockerk8s.yaml" + dns="localhost" +fi + +if [[ $dns == "aks" ]]; then + echo "#################### Begin AKS discovery based on the --dns aks setting. ####################" + if [[ -z $aks_name ]] || [[ -z $aks_rg ]]; then + echo "Error: When using -dns aks, MUST set -aksName and -aksRg too." + echo '' + usage + exit 1 + fi + + echo "Getting DNS of AKS of AKS $aks_name (in resource group $aks_rg)" + dns="$(az aks show -n $aks_name -g $aks_rg --query addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName)" + if [[ -z dns ]]; then + echo "Error: when getting DNS of AKS $aks_name (in resource group $aks_rg). Please ensure AKS has httpRouting enabled AND Azure CLI is logged in and is of version 2.0.37 or higher." + exit 1 + fi + $dns=${dns//[\"]/""} + echo "DNS base found is $dns. Will use $aks_name.$dns for the app!" +fi + +# Initialization & check commands +if [[ -z $dns ]]; then + echo "No DNS specified. Ingress resources will be bound to public IP." +fi + +if [[ $clean ]]; then + echo "Cleaning previous helm releases..." + helm delete --purge $(helm ls -q) + echo "Previous releases deleted" +fi + +use_custom_registry='yes' + +if [[ -n $container_registry ]]; then + use_custom_registry='yes' + if [[ -z $docker_user ]] || [[ -z $docker_password ]]; then + echo "Error: Must use -u (--docker-username) AND -p (--docker-password) if specifying custom registry" + exit 1 + fi +fi + +echo "#################### Begin $app_name installation using Helm ####################" +infras=(sql-data nosql-data rabbitmq keystore-data basket-data) +charts=(eshop-common apigwmm apigwms apigwwm apigwws basket-api catalog-api identity-api locations-api marketing-api mobileshoppingagg ordering-api ordering-backgroundtasks ordering-signalrhub payment-api webmvc webshoppingagg webspa webstatus webhooks-api webhooks-web) + +if [[ !$skip_infrastructure ]]; then + for infra in "${infras[@]}" + do + echo "Installing infrastructure: $infra" + helm install --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --name="$app_name-$infra" $infra + done +fi + +for chart in "${charts[@]}" +do + echo "Installing: $chart" + if [[ $use_custom_registry ]]; then + helm install --set inf.registry.server=$container_registry --set inf.registry.login=$docker_username --set inf.registry.pwd=$docker_password --set inf.registry.secretName=eshop-docker-scret --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always --name="$app_name-$chart" $chart + elif [[ $chart != "eshop-common" ]]; then # eshop-common is ignored when no secret must be deployed + helm install --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always --name="$app_name-$chart" $chart + fi +done + +echo "FINISHED: Helm charts installed." \ No newline at end of file From 46590874a76225dea7414655e96423cffc8dadda Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Fri, 8 Mar 2019 14:03:14 +0100 Subject: [PATCH 2/9] Build correct solution --- k8s/helm/deploy-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/helm/deploy-all.sh b/k8s/helm/deploy-all.sh index adfb111f3..f331c8ece 100755 --- a/k8s/helm/deploy-all.sh +++ b/k8s/helm/deploy-all.sh @@ -111,7 +111,7 @@ done if [[ $build_solution ]]; then echo "#################### Building $app_name solution ####################" - dotnet publish -o obj/Docker/publish ../../winnersworkout-backend.sln + dotnet publish -o obj/Docker/publish ../../eShopOnContainers-ServicesAndWebApps.sln fi export TAG=$image_tag From 45755aff0b1b9e7125b2da71fc6b663bf431acc8 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Fri, 8 Mar 2019 16:16:50 +0100 Subject: [PATCH 3/9] Fix path error in docker-compose command --- k8s/helm/deploy-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/helm/deploy-all.sh b/k8s/helm/deploy-all.sh index f331c8ece..1698a11a8 100755 --- a/k8s/helm/deploy-all.sh +++ b/k8s/helm/deploy-all.sh @@ -118,7 +118,7 @@ export TAG=$image_tag if [[ $build_images ]]; then echo "#################### Building the $app_name Docker images ####################" - docker-compose -p .. -f ../../docker-compose.yml build + docker-compose -p ../.. -f ../../docker-compose.yml build # Remove temporary images docker rmi $(docker images -qf "dangling=true") From e5ee6d735c7f71907128cc8f030d77eaefee06aa Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Mon, 11 Mar 2019 13:20:40 +0100 Subject: [PATCH 4/9] Fix initialization of the use_custom_registry boolean --- k8s/helm/deploy-all.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/k8s/helm/deploy-all.sh b/k8s/helm/deploy-all.sh index 1698a11a8..3ec209aa1 100755 --- a/k8s/helm/deploy-all.sh +++ b/k8s/helm/deploy-all.sh @@ -173,7 +173,7 @@ if [[ $clean ]]; then echo "Previous releases deleted" fi -use_custom_registry='yes' +use_custom_registry='' if [[ -n $container_registry ]]; then use_custom_registry='yes' @@ -205,4 +205,4 @@ do fi done -echo "FINISHED: Helm charts installed." \ No newline at end of file +echo "FINISHED: Helm charts installed." From 954dd4893a0413281c510dbb9d527a452d3039df Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Tue, 12 Mar 2019 11:47:24 +0100 Subject: [PATCH 5/9] Correctly set the backing field for the use-local-k8s parameter --- k8s/helm/deploy-all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k8s/helm/deploy-all.sh b/k8s/helm/deploy-all.sh index 3ec209aa1..705b172f5 100755 --- a/k8s/helm/deploy-all.sh +++ b/k8s/helm/deploy-all.sh @@ -102,7 +102,7 @@ while [[ $# -gt 0 ]]; do -u | --docker-username ) docker_username="$2"; shift 2;; --use-local-k8s ) - use_local_k8s=''; shift ;; + use_local_k8s='yes'; shift ;; *) echo "Unknown option $1" usage; exit 2 ;; From a92383e123b9e2abb7971442dc708ffc60514552 Mon Sep 17 00:00:00 2001 From: liubaishui Date: Fri, 15 Mar 2019 21:03:42 +0800 Subject: [PATCH 6/9] Split RabbitMQ channel create and consumer create. Because when channel create the Subscribe is not register, so the previously stored message may lose. This fix split the channel create and consumer create, when Subscribe registered then call the consumer create function. --- .../EventBusRabbitMQ/EventBusRabbitMQ.cs | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index ac379d50a..9044a4283 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -98,7 +98,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ channel.BasicPublish(exchange: BROKER_NAME, routingKey: eventName, - mandatory:true, + mandatory: true, basicProperties: properties, body: body); }); @@ -112,6 +112,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ DoInternalSubscription(eventName); _subsManager.AddDynamicSubscription(eventName); + StartBasicConsume(); } public void Subscribe() @@ -124,6 +125,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); _subsManager.AddSubscription(); + StartBasicConsume(); } private void DoInternalSubscription(string eventName) @@ -172,6 +174,31 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _subsManager.Clear(); } + private void StartBasicConsume() + { + if (_consumerChannel != null) + { + var consumer = new EventingBasicConsumer(_consumerChannel); + consumer.Received += async (model, ea) => + { + var eventName = ea.RoutingKey; + var message = Encoding.UTF8.GetString(ea.Body); + + await ProcessEvent(eventName, message); + + _consumerChannel.BasicAck(ea.DeliveryTag, multiple: false); + }; + + _consumerChannel.BasicConsume(queue: _queueName, + autoAck: false, + consumer: consumer); + } + else + { + _logger.LogError("StartBasicConsume can not call on _consumerChannelCreated == false"); + } + } + private IModel CreateConsumerChannel() { if (!_persistentConnection.IsConnected) @@ -190,26 +217,11 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ autoDelete: false, arguments: null); - - var consumer = new EventingBasicConsumer(channel); - consumer.Received += async (model, ea) => - { - var eventName = ea.RoutingKey; - var message = Encoding.UTF8.GetString(ea.Body); - - await ProcessEvent(eventName, message); - - channel.BasicAck(ea.DeliveryTag,multiple:false); - }; - - channel.BasicConsume(queue: _queueName, - autoAck: false, - consumer: consumer); - channel.CallbackException += (sender, ea) => { _consumerChannel.Dispose(); _consumerChannel = CreateConsumerChannel(); + StartBasicConsume(); }; return channel; From 1255e5f6044168f55c94e7c224c3f11ad192c0bb Mon Sep 17 00:00:00 2001 From: jmanuelcorral Date: Wed, 27 Mar 2019 16:08:27 +0100 Subject: [PATCH 7/9] Updated Bootstrap to 4.3.1 to fix security issues --- src/Web/WebSPA/package-lock.json | 6 +++--- src/Web/WebSPA/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Web/WebSPA/package-lock.json b/src/Web/WebSPA/package-lock.json index 8386a6cf9..ea4aac4fd 100644 --- a/src/Web/WebSPA/package-lock.json +++ b/src/Web/WebSPA/package-lock.json @@ -2887,9 +2887,9 @@ } }, "bootstrap": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz", - "integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz", + "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==" }, "boxen": { "version": "1.3.0", diff --git a/src/Web/WebSPA/package.json b/src/Web/WebSPA/package.json index 2adfb5d84..11cb0b882 100644 --- a/src/Web/WebSPA/package.json +++ b/src/Web/WebSPA/package.json @@ -39,7 +39,7 @@ "@angular/router": "^7.2.10", "@aspnet/signalr": "1.0.3", "@ng-bootstrap/ng-bootstrap": "3.3.0", - "bootstrap": "4.1.3", + "bootstrap": "4.3.1", "core-js": "^2.5.0", "file-loader": "2.0.0", "font-awesome": "4.7.0", From 9192046f71b3fc48ae57cea835d70175b7af178b Mon Sep 17 00:00:00 2001 From: jmanuelcorral Date: Wed, 27 Mar 2019 16:50:49 +0100 Subject: [PATCH 8/9] Fixed some security issues with npm audit --- src/Web/WebSPA/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Web/WebSPA/package-lock.json b/src/Web/WebSPA/package-lock.json index ea4aac4fd..9a1e9af96 100644 --- a/src/Web/WebSPA/package-lock.json +++ b/src/Web/WebSPA/package-lock.json @@ -6959,9 +6959,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz", + "integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==", "dev": true, "requires": { "argparse": "^1.0.7", From e5630a322ab6fc15b5d557556cd7dd0fa1f25ded Mon Sep 17 00:00:00 2001 From: eiximenis Date: Thu, 28 Mar 2019 10:11:53 +0100 Subject: [PATCH 9/9] infrastructure build --- .../infrastructure/azure-pipelines.yml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 build/azure-devops/infrastructure/azure-pipelines.yml diff --git a/build/azure-devops/infrastructure/azure-pipelines.yml b/build/azure-devops/infrastructure/azure-pipelines.yml new file mode 100644 index 000000000..50296d457 --- /dev/null +++ b/build/azure-devops/infrastructure/azure-pipelines.yml @@ -0,0 +1,25 @@ +pool: + vmImage: 'ubuntu-16.04' +variables: + registryEndpoint: eshop-registry +trigger: + branches: + include: + - master + - dev + paths: + include: + - k8s/helm/basket-data/* + - k8s/helm/keystore-data/* + - k8s/helm/nosql-data/* + - k8s/helm/rabbitmq/* + - k8s/helm/sql-data/* +steps: +- task: CopyFiles@2 + inputs: + sourceFolder: $(Build.SourcesDirectory)/k8s/helm + targetFolder: $(Build.ArtifactStagingDirectory)/k8s/helm +- task: PublishBuildArtifacts@1 + inputs: + pathtoPublish: $(Build.ArtifactStagingDirectory)/k8s/helm + artifactName: helm