Merge branch 'dev' into features/addELKSupport
This commit is contained in:
commit
3c971132eb
25
build/azure-devops/infrastructure/azure-pipelines.yml
Normal file
25
build/azure-devops/infrastructure/azure-pipelines.yml
Normal file
@ -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
|
208
k8s/helm/deploy-all.sh
Executable file
208
k8s/helm/deploy-all.sh
Executable file
@ -0,0 +1,208 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# http://redsymbol.net/articles/unofficial-bash-strict-mode
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
cat <<END
|
||||||
|
deploy.sh: deploys the $app_name application to a Kubernetes cluster using Helm.
|
||||||
|
Parameters:
|
||||||
|
--aks-name <AKS cluster name>
|
||||||
|
The name of the AKS cluster. Required when the registry (using the -r parameter) is set to "aks".
|
||||||
|
--aks-rg <AKS resource group>
|
||||||
|
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 <dns or ip address>
|
||||||
|
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 <the name of the app>
|
||||||
|
Specifies the name of the application (default: eshop).
|
||||||
|
-p | --docker-password <docker password>
|
||||||
|
The Docker password used to logon to the custom registry, supplied using the -r parameter.
|
||||||
|
-r | --registry <container 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 <docker image tag>
|
||||||
|
The tag used for the newly created docker images. Default: newly created, date-based timestamp, with 1-minute resolution.
|
||||||
|
-u | --docker-user <docker username>
|
||||||
|
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='yes'; 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 ../../eShopOnContainers-ServicesAndWebApps.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=''
|
||||||
|
|
||||||
|
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."
|
@ -98,7 +98,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
|
|
||||||
channel.BasicPublish(exchange: BROKER_NAME,
|
channel.BasicPublish(exchange: BROKER_NAME,
|
||||||
routingKey: eventName,
|
routingKey: eventName,
|
||||||
mandatory:true,
|
mandatory: true,
|
||||||
basicProperties: properties,
|
basicProperties: properties,
|
||||||
body: body);
|
body: body);
|
||||||
});
|
});
|
||||||
@ -112,6 +112,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
|
|
||||||
DoInternalSubscription(eventName);
|
DoInternalSubscription(eventName);
|
||||||
_subsManager.AddDynamicSubscription<TH>(eventName);
|
_subsManager.AddDynamicSubscription<TH>(eventName);
|
||||||
|
StartBasicConsume();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Subscribe<T, TH>()
|
public void Subscribe<T, TH>()
|
||||||
@ -124,6 +125,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
_logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName());
|
_logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName());
|
||||||
|
|
||||||
_subsManager.AddSubscription<T, TH>();
|
_subsManager.AddSubscription<T, TH>();
|
||||||
|
StartBasicConsume();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoInternalSubscription(string eventName)
|
private void DoInternalSubscription(string eventName)
|
||||||
@ -172,6 +174,31 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
_subsManager.Clear();
|
_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()
|
private IModel CreateConsumerChannel()
|
||||||
{
|
{
|
||||||
if (!_persistentConnection.IsConnected)
|
if (!_persistentConnection.IsConnected)
|
||||||
@ -190,26 +217,11 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
|
|||||||
autoDelete: false,
|
autoDelete: false,
|
||||||
arguments: null);
|
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) =>
|
channel.CallbackException += (sender, ea) =>
|
||||||
{
|
{
|
||||||
_consumerChannel.Dispose();
|
_consumerChannel.Dispose();
|
||||||
_consumerChannel = CreateConsumerChannel();
|
_consumerChannel = CreateConsumerChannel();
|
||||||
|
StartBasicConsume();
|
||||||
};
|
};
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
|
12
src/Web/WebSPA/package-lock.json
generated
12
src/Web/WebSPA/package-lock.json
generated
@ -2887,9 +2887,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bootstrap": {
|
"bootstrap": {
|
||||||
"version": "4.1.3",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
|
||||||
"integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w=="
|
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
|
||||||
},
|
},
|
||||||
"boxen": {
|
"boxen": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
@ -6959,9 +6959,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"js-yaml": {
|
"js-yaml": {
|
||||||
"version": "3.12.0",
|
"version": "3.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz",
|
||||||
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
|
"integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^1.0.7",
|
"argparse": "^1.0.7",
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
"@angular/router": "^7.2.10",
|
"@angular/router": "^7.2.10",
|
||||||
"@aspnet/signalr": "1.0.3",
|
"@aspnet/signalr": "1.0.3",
|
||||||
"@ng-bootstrap/ng-bootstrap": "3.3.0",
|
"@ng-bootstrap/ng-bootstrap": "3.3.0",
|
||||||
"bootstrap": "4.1.3",
|
"bootstrap": "4.3.1",
|
||||||
"core-js": "^2.5.0",
|
"core-js": "^2.5.0",
|
||||||
"file-loader": "2.0.0",
|
"file-loader": "2.0.0",
|
||||||
"font-awesome": "4.7.0",
|
"font-awesome": "4.7.0",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user