mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-04-07 01:08:47 +02:00
Compare commits
15 Commits
v0.7.0
...
release-0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20693fd44c | ||
|
|
37bb65b0ac | ||
|
|
da7be2e3ca | ||
|
|
d138c10eb6 | ||
|
|
4af13eba60 | ||
|
|
e998e499db | ||
|
|
53cdced69b | ||
|
|
e726da46a5 | ||
|
|
b0d6a7092e | ||
|
|
1fe870c0d7 | ||
|
|
469cf1d164 | ||
|
|
00299707e5 | ||
|
|
9f5a718323 | ||
|
|
231d86e249 | ||
|
|
5fb8b3f73c |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,5 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## v0.7.2 (2018-08-21)
|
||||
- API discovery becomes best effort when partial resource list is returned (issue #524)
|
||||
|
||||
## v0.7.1 (2018-08-03)
|
||||
+ Surface helm parameters to the application level (#485)
|
||||
+ [UI] Improve application creation wizard (#459)
|
||||
+ [UI] Show indicator when refresh is still in progress (#493)
|
||||
* [UI] Improve data loading error notification (#446)
|
||||
* Infer username from claims during an `argocd relogin` (#475)
|
||||
* Expand RBAC role to be able to create application events. Fix username claims extraction
|
||||
- Fix scalability issues with the ListApps API (#494)
|
||||
- Fix issue where application server was retrieving events from incorrect cluster (#478)
|
||||
- Fix failure in identifying app source type when path was '.'
|
||||
- AppProjectSpec SourceRepos mislabeled (#490)
|
||||
- Failed e2e test was not failing CI workflow
|
||||
* Fix linux download link in getting_started.md (#487) (@chocopowwwa)
|
||||
|
||||
## v0.7.0 (2018-07-27)
|
||||
+ Support helm charts and yaml directories as an application source
|
||||
+ Audit trails in the form of API call logs
|
||||
|
||||
@@ -38,6 +38,18 @@ NOTE: The make command can take a while, and we recommend building the specific
|
||||
* `make codegen` - Builds protobuf and swagger files
|
||||
* `make argocd-util` - Make the administrator's utility, used for certain tasks such as import/export
|
||||
|
||||
## Generating ArgoCD manifests for a specific image repository/tag
|
||||
|
||||
During development, the `update-manifests.sh` script, can be used to conveniently regenerate the
|
||||
ArgoCD installation manifests with a customized image namespace and tag. This enables developers
|
||||
to easily apply manifests which are using the images that they pushed into their personal container
|
||||
repository.
|
||||
|
||||
```
|
||||
$ IMAGE_NAMESPACE=jessesuen IMAGE_TAG=latest ./hack/update-manifests.sh
|
||||
$ kubectl apply -n argocd -f ./manifests/install.yaml
|
||||
```
|
||||
|
||||
## Running locally
|
||||
|
||||
You need to have access to kubernetes cluster (including [minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) or [docker edge](https://docs.docker.com/docker-for-mac/install/) ) in order to run Argo CD on your laptop:
|
||||
|
||||
370
Gopkg.lock
generated
370
Gopkg.lock
generated
File diff suppressed because it is too large
Load Diff
3
Makefile
3
Makefile
@@ -81,8 +81,7 @@ argocd-util: clean-debug
|
||||
.PHONY: install-manifest
|
||||
install-manifest:
|
||||
if [ "${IMAGE_NAMESPACE}" = "" ] ; then echo "IMAGE_NAMESPACE must be set to build install manifest" ; exit 1 ; fi
|
||||
echo "# This is an auto-generated file. DO NOT EDIT" > manifests/install.yaml
|
||||
cat manifests/components/*.yaml | sed 's@\( image: argoproj/\(.*\):latest\)@ image: '"${IMAGE_NAMESPACE}"'/\2:'"${IMAGE_TAG}"'@g' >> manifests/install.yaml
|
||||
./hack/update-manifests.sh
|
||||
|
||||
.PHONY: server
|
||||
server: clean-debug
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
## What is Argo CD?
|
||||
|
||||
Argo CD is a declarative, continuous delivery for Kubernetes.
|
||||
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
|
||||
|
||||

|
||||
|
||||
@@ -55,13 +55,15 @@ For additional details, see [architecture overview](docs/architecture.md).
|
||||
* SSO Integration (OIDC, OAuth2, LDAP, SAML 2.0, GitLab, Microsoft, LinkedIn)
|
||||
* Webhook Integration (GitHub, BitBucket, GitLab)
|
||||
* PreSync, Sync, PostSync hooks to support complex application rollouts (e.g.blue/green & canary upgrades)
|
||||
* Audit trails for application events and API calls
|
||||
* Parameter overrides for overriding ksonnet/helm parameters in git
|
||||
|
||||
## Development Status
|
||||
* Argo CD is being used in production to deploy SaaS services at Intuit
|
||||
|
||||
## Roadmap
|
||||
* Audit trails for application events and API calls
|
||||
* Auto-sync toggle to directly apply git state changes to live state
|
||||
* Service account/access key management for CI pipelines
|
||||
* Revamped UI
|
||||
* Support for additional config management tools (Kustomize?)
|
||||
* Revamped UI, and feature parity with CLI
|
||||
* Customizable application actions
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
// NewReloginCommand returns a new instance of `argocd relogin` command
|
||||
func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
var (
|
||||
username string
|
||||
password string
|
||||
)
|
||||
var command = &cobra.Command{
|
||||
@@ -54,8 +53,10 @@ func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comm
|
||||
PlainText: configCtx.Server.PlainText,
|
||||
}
|
||||
acdClient := argocdclient.NewClientOrDie(&clientOpts)
|
||||
tokenString = passwordLogin(acdClient, username, password)
|
||||
fmt.Printf("Relogging in as '%s'\n", claims.Subject)
|
||||
tokenString = passwordLogin(acdClient, claims.Subject, password)
|
||||
} else {
|
||||
fmt.Println("Reinitiating SSO login")
|
||||
tokenString, refreshToken = oauth2Login(configCtx.Server.Server, configCtx.Server.PlainText)
|
||||
}
|
||||
|
||||
@@ -69,7 +70,6 @@ func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comm
|
||||
fmt.Printf("Context '%s' updated\n", localCfg.CurrentContext)
|
||||
},
|
||||
}
|
||||
command.Flags().StringVar(&username, "username", "", "the username of an account to authenticate")
|
||||
command.Flags().StringVar(&password, "password", "", "the password of an account to authenticate")
|
||||
return command
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ func NewApplicationController(
|
||||
statusRefreshTimeout: appResyncPeriod,
|
||||
forceRefreshApps: make(map[string]bool),
|
||||
forceRefreshAppsMutex: &sync.Mutex{},
|
||||
auditLogger: argo.NewAuditLogger(namespace, kubeClientset, "appcontroller"),
|
||||
auditLogger: argo.NewAuditLogger(namespace, kubeClientset, "application-controller"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ func retryUntilSucceed(action func() error, desc string, ctx context.Context, ti
|
||||
log.Infof("Stop retrying %s", desc)
|
||||
return
|
||||
} else {
|
||||
log.Warnf("Failed to %s: %v, retrying in %v", desc, err, timeout)
|
||||
log.Warnf("Failed to %s: %+v, retrying in %v", desc, err, timeout)
|
||||
time.Sleep(timeout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,21 +9,29 @@ An example guestbook application is provided to demonstrate how ArgoCD works.
|
||||
## 1. Install ArgoCD
|
||||
```
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v0.7.1/manifests/install.yaml
|
||||
```
|
||||
This will create a new namespace, `argocd`, where ArgoCD services and application resources will live.
|
||||
|
||||
NOTE:
|
||||
* On GKE with RBAC enabled, you may need to grant your account the ability to create new cluster roles
|
||||
```
|
||||
$ kubectl create clusterrolebinding YOURNAME-cluster-admin-binding --clusterrole=cluster-admin --user=YOUREMAIL@gmail.com
|
||||
kubectl create clusterrolebinding YOURNAME-cluster-admin-binding --clusterrole=cluster-admin --user=YOUREMAIL@gmail.com
|
||||
```
|
||||
|
||||
## 2. Download ArgoCD CLI
|
||||
|
||||
Download the latest ArgoCD version:
|
||||
|
||||
On Mac:
|
||||
```
|
||||
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v0.7.0/argocd-darwin-amd64
|
||||
brew install argoproj/tap/argocd
|
||||
```
|
||||
|
||||
On Linux:
|
||||
|
||||
```
|
||||
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v0.7.1/argocd-linux-amd64
|
||||
chmod +x /usr/local/bin/argocd
|
||||
```
|
||||
|
||||
@@ -59,6 +67,7 @@ argocd login <EXTERNAL-IP>
|
||||
After logging in, change the password using the command:
|
||||
```
|
||||
argocd account update-password
|
||||
argocd relogin
|
||||
```
|
||||
|
||||
|
||||
|
||||
11
hack/update-manifests.sh
Executable file
11
hack/update-manifests.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
IMAGE_NAMESPACE=${IMAGE_NAMESPACE:='argoproj'}
|
||||
IMAGE_TAG=${IMAGE_TAG:='latest'}
|
||||
|
||||
for i in "$(ls manifests/components/*.yaml)"; do
|
||||
sed -i '' 's@\( image: \(.*\)/\(argocd-.*\):.*\)@ image: '"${IMAGE_NAMESPACE}"'/\3:'"${IMAGE_TAG}"'@g' $i
|
||||
done
|
||||
|
||||
echo "# This is an auto-generated file. DO NOT EDIT" > manifests/install.yaml
|
||||
cat manifests/components/*.yaml >> manifests/install.yaml
|
||||
@@ -27,3 +27,11 @@ rules:
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- list
|
||||
|
||||
|
||||
@@ -14,6 +14,6 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- command: [/argocd-application-controller, --repo-server, 'argocd-repo-server:8081']
|
||||
image: argoproj/argocd-application-controller:latest
|
||||
image: argoproj/argocd-application-controller:v0.7.2
|
||||
name: application-controller
|
||||
serviceAccountName: application-controller
|
||||
|
||||
@@ -30,3 +30,10 @@ rules:
|
||||
- update
|
||||
- delete
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- list
|
||||
|
||||
@@ -15,20 +15,20 @@ spec:
|
||||
serviceAccountName: argocd-server
|
||||
initContainers:
|
||||
- name: copyutil
|
||||
image: argoproj/argocd-server:latest
|
||||
image: argoproj/argocd-server:v0.7.2
|
||||
command: [cp, /argocd-util, /shared]
|
||||
volumeMounts:
|
||||
- mountPath: /shared
|
||||
name: static-files
|
||||
- name: ui
|
||||
image: argoproj/argocd-ui:latest
|
||||
image: argoproj/argocd-ui:v0.7.2
|
||||
command: [cp, -r, /app, /shared]
|
||||
volumeMounts:
|
||||
- mountPath: /shared
|
||||
name: static-files
|
||||
containers:
|
||||
- name: argocd-server
|
||||
image: argoproj/argocd-server:latest
|
||||
image: argoproj/argocd-server:v0.7.2
|
||||
command: [/argocd-server, --staticassets, /shared/app, --repo-server, 'argocd-repo-server:8081']
|
||||
volumeMounts:
|
||||
- mountPath: /shared
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: argocd-repo-server
|
||||
image: argoproj/argocd-repo-server:latest
|
||||
image: argoproj/argocd-repo-server:v0.7.2
|
||||
command: [/argocd-repo-server]
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
|
||||
@@ -126,6 +126,14 @@ rules:
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- list
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
@@ -154,7 +162,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- command: [/argocd-application-controller, --repo-server, 'argocd-repo-server:8081']
|
||||
image: argoproj/argocd-application-controller:v0.7.0
|
||||
image: argoproj/argocd-application-controller:v0.7.2
|
||||
name: application-controller
|
||||
serviceAccountName: application-controller
|
||||
---
|
||||
@@ -194,6 +202,13 @@ rules:
|
||||
- update
|
||||
- delete
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- list
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
@@ -223,20 +238,20 @@ spec:
|
||||
serviceAccountName: argocd-server
|
||||
initContainers:
|
||||
- name: copyutil
|
||||
image: argoproj/argocd-server:v0.7.0
|
||||
image: argoproj/argocd-server:v0.7.2
|
||||
command: [cp, /argocd-util, /shared]
|
||||
volumeMounts:
|
||||
- mountPath: /shared
|
||||
name: static-files
|
||||
- name: ui
|
||||
image: argoproj/argocd-ui:v0.7.0
|
||||
image: argoproj/argocd-ui:v0.7.2
|
||||
command: [cp, -r, /app, /shared]
|
||||
volumeMounts:
|
||||
- mountPath: /shared
|
||||
name: static-files
|
||||
containers:
|
||||
- name: argocd-server
|
||||
image: argoproj/argocd-server:v0.7.0
|
||||
image: argoproj/argocd-server:v0.7.2
|
||||
command: [/argocd-server, --staticassets, /shared/app, --repo-server, 'argocd-repo-server:8081']
|
||||
volumeMounts:
|
||||
- mountPath: /shared
|
||||
@@ -283,7 +298,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: argocd-repo-server
|
||||
image: argoproj/argocd-repo-server:v0.7.0
|
||||
image: argoproj/argocd-repo-server:v0.7.2
|
||||
command: [/argocd-repo-server]
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
|
||||
@@ -7781,153 +7781,153 @@ var fileDescriptorGenerated = []byte{
|
||||
0x19, 0x76, 0xcf, 0x6b, 0x67, 0xfe, 0xd9, 0x87, 0x5d, 0x79, 0x30, 0x38, 0xd2, 0xee, 0xaa, 0xc3,
|
||||
0xc3, 0xa0, 0x64, 0x06, 0x1b, 0x02, 0xe6, 0x21, 0x24, 0xcf, 0xae, 0x1d, 0x6f, 0xd6, 0x8f, 0xa5,
|
||||
0x66, 0x13, 0xa4, 0x10, 0x05, 0xda, 0x3d, 0xb5, 0x33, 0xed, 0x99, 0xe9, 0xee, 0x74, 0xd5, 0x8c,
|
||||
0x35, 0x12, 0x41, 0x46, 0x08, 0x89, 0xa7, 0x04, 0x42, 0x88, 0x2b, 0x07, 0x4e, 0x08, 0x09, 0x09,
|
||||
0x71, 0x42, 0xe2, 0x00, 0x07, 0xe4, 0x63, 0x0e, 0x20, 0xa2, 0x80, 0x56, 0x78, 0x73, 0x89, 0xc4,
|
||||
0x81, 0x7b, 0x4e, 0xa8, 0x1e, 0xdd, 0x55, 0xdd, 0xb3, 0xcb, 0xae, 0x3d, 0x6d, 0x03, 0xb7, 0xee,
|
||||
0xff, 0xff, 0xfb, 0xff, 0xfe, 0xfa, 0xeb, 0xaf, 0xff, 0x51, 0x0d, 0x5b, 0x3d, 0x8f, 0xf5, 0xc7,
|
||||
0xb7, 0x9a, 0x6e, 0x30, 0x6a, 0x39, 0x51, 0x2f, 0x08, 0xa3, 0xe0, 0xb6, 0x78, 0x78, 0xde, 0xed,
|
||||
0xb6, 0xc2, 0x41, 0xaf, 0xe5, 0x84, 0x1e, 0x6d, 0x39, 0x61, 0x38, 0xf4, 0x5c, 0x87, 0x79, 0x81,
|
||||
0xdf, 0x9a, 0x9c, 0x77, 0x86, 0x61, 0xdf, 0x39, 0xdf, 0xea, 0x11, 0x9f, 0x44, 0x0e, 0x23, 0xdd,
|
||||
0x66, 0x18, 0x05, 0x2c, 0x40, 0x9f, 0xd5, 0xaa, 0x9a, 0xb1, 0x2a, 0xf1, 0xf0, 0x55, 0xb7, 0xdb,
|
||||
0x0c, 0x07, 0xbd, 0x26, 0x57, 0xd5, 0x34, 0x54, 0x35, 0x63, 0x55, 0x67, 0x9f, 0x37, 0xac, 0xe8,
|
||||
0x05, 0xbd, 0xa0, 0x25, 0x34, 0xde, 0x1a, 0xef, 0x89, 0x37, 0xf1, 0x22, 0x9e, 0x24, 0xd2, 0xd9,
|
||||
0x4f, 0x0d, 0x2e, 0xd2, 0xa6, 0x17, 0x70, 0xdb, 0x46, 0x8e, 0xdb, 0xf7, 0x7c, 0x12, 0x4d, 0xb5,
|
||||
0xb1, 0x23, 0xc2, 0x9c, 0xd6, 0x64, 0xc6, 0xbe, 0xb3, 0xad, 0xa3, 0xbe, 0x8a, 0xc6, 0x3e, 0xf3,
|
||||
0x46, 0x64, 0xe6, 0x83, 0x4f, 0x1f, 0xf7, 0x01, 0x75, 0xfb, 0x64, 0xe4, 0xcc, 0x7c, 0xf7, 0xc9,
|
||||
0xa3, 0xbe, 0x1b, 0x33, 0x6f, 0xd8, 0xf2, 0x7c, 0x46, 0x59, 0x94, 0xfd, 0xc8, 0xfe, 0x9b, 0x05,
|
||||
0x70, 0x29, 0x0c, 0x77, 0xa2, 0xe0, 0x36, 0x71, 0x19, 0xfa, 0x1a, 0x54, 0xf9, 0x3a, 0xba, 0x0e,
|
||||
0x73, 0x1a, 0xd6, 0xba, 0x75, 0xae, 0x7e, 0xe1, 0x13, 0x4d, 0xa9, 0xb6, 0x69, 0xaa, 0xd5, 0x7e,
|
||||
0xe5, 0xd2, 0xcd, 0xc9, 0xf9, 0xe6, 0xcd, 0x5b, 0xfc, 0xfb, 0xeb, 0x84, 0x39, 0x6d, 0x74, 0x6f,
|
||||
0x7f, 0xed, 0xd4, 0xc1, 0xfe, 0x1a, 0x68, 0x1a, 0x4e, 0xb4, 0xa2, 0x01, 0x94, 0x68, 0x48, 0xdc,
|
||||
0x46, 0x41, 0x68, 0xdf, 0x6a, 0x3e, 0xf4, 0xee, 0x35, 0xb5, 0xd9, 0x9d, 0x90, 0xb8, 0xed, 0x45,
|
||||
0x05, 0x5b, 0xe2, 0x6f, 0x58, 0x80, 0xd8, 0xef, 0x58, 0xb0, 0xac, 0xc5, 0xae, 0x79, 0x94, 0xa1,
|
||||
0xd7, 0x66, 0x56, 0xd8, 0x3c, 0xd9, 0x0a, 0xf9, 0xd7, 0x62, 0x7d, 0xa7, 0x15, 0x50, 0x35, 0xa6,
|
||||
0x18, 0xab, 0xbb, 0x0d, 0x65, 0x8f, 0x91, 0x11, 0x6d, 0x14, 0xd6, 0x8b, 0xe7, 0xea, 0x17, 0x2e,
|
||||
0xe7, 0xb2, 0xbc, 0xf6, 0x92, 0x42, 0x2c, 0x6f, 0x71, 0xdd, 0x58, 0x42, 0xd8, 0x77, 0x0b, 0xe6,
|
||||
0xe2, 0xf8, 0xaa, 0xd1, 0xc7, 0x60, 0x81, 0x06, 0xe3, 0xc8, 0x25, 0xb4, 0x61, 0xad, 0x17, 0xcf,
|
||||
0xd5, 0xda, 0x2b, 0x07, 0xfb, 0x6b, 0xf5, 0x8e, 0x20, 0x61, 0x12, 0x06, 0x14, 0xc7, 0x7c, 0xf4,
|
||||
0x7d, 0x0b, 0x16, 0xbb, 0x84, 0x32, 0xcf, 0x17, 0xb8, 0xb1, 0xc5, 0x5f, 0x9a, 0xcf, 0xe2, 0x98,
|
||||
0xb8, 0xa9, 0x35, 0xb7, 0x9f, 0x54, 0xd6, 0x2f, 0x1a, 0x44, 0x8a, 0x53, 0xe0, 0xe8, 0x05, 0xa8,
|
||||
0x77, 0x09, 0x75, 0x23, 0x2f, 0xe4, 0xef, 0x8d, 0xe2, 0xba, 0x75, 0xae, 0xd6, 0x7e, 0x42, 0x7d,
|
||||
0x58, 0xdf, 0xd4, 0x2c, 0x6c, 0xca, 0xd9, 0x7f, 0x2a, 0x42, 0xdd, 0x40, 0x7d, 0x0c, 0xe1, 0x3b,
|
||||
0x4c, 0x85, 0xef, 0x4b, 0xf9, 0x78, 0xeb, 0xa8, 0xf8, 0x45, 0x0c, 0x2a, 0x94, 0x39, 0x6c, 0x4c,
|
||||
0x85, 0x47, 0xea, 0x17, 0xae, 0xe5, 0x84, 0x27, 0x74, 0xb6, 0x97, 0x15, 0x62, 0x45, 0xbe, 0x63,
|
||||
0x85, 0x85, 0xde, 0x80, 0x5a, 0x10, 0xf2, 0x2c, 0xc1, 0xb7, 0xa2, 0x24, 0x80, 0x37, 0xe7, 0x00,
|
||||
0xbe, 0x19, 0xeb, 0x6a, 0x2f, 0x1d, 0xec, 0xaf, 0xd5, 0x92, 0x57, 0xac, 0x51, 0x6c, 0x17, 0x9e,
|
||||
0x34, 0xec, 0xdb, 0x08, 0xfc, 0xae, 0x27, 0x36, 0x74, 0x1d, 0x4a, 0x6c, 0x1a, 0x12, 0xb1, 0x99,
|
||||
0x35, 0xed, 0xa2, 0xdd, 0x69, 0x48, 0xb0, 0xe0, 0xf0, 0x90, 0x1f, 0x11, 0x4a, 0x9d, 0x1e, 0x11,
|
||||
0x7b, 0x52, 0x6b, 0xaf, 0x28, 0xa1, 0x85, 0xeb, 0x92, 0x8c, 0x63, 0xbe, 0xfd, 0x06, 0x3c, 0x7d,
|
||||
0x78, 0x88, 0xa2, 0x8f, 0x40, 0x85, 0x92, 0x68, 0x42, 0x22, 0x05, 0xa4, 0x3d, 0x23, 0xa8, 0x58,
|
||||
0x71, 0x51, 0x0b, 0x6a, 0xbe, 0x33, 0x22, 0x34, 0x74, 0xdc, 0x18, 0xee, 0x8c, 0x12, 0xad, 0xdd,
|
||||
0x88, 0x19, 0x58, 0xcb, 0xd8, 0x7f, 0xb7, 0x60, 0xc5, 0xc0, 0x7c, 0x0c, 0x19, 0x68, 0x90, 0xce,
|
||||
0x40, 0x57, 0xf2, 0x89, 0x98, 0x23, 0x52, 0xd0, 0x1f, 0x8a, 0x70, 0xc6, 0x8c, 0x2b, 0x91, 0x5b,
|
||||
0xf8, 0x96, 0x44, 0x24, 0x0c, 0x5e, 0xc6, 0xd7, 0x94, 0x3b, 0x93, 0x2d, 0xc1, 0x92, 0x8c, 0x63,
|
||||
0x3e, 0xdf, 0xdf, 0xd0, 0x61, 0x7d, 0xe5, 0xcb, 0x64, 0x7f, 0x77, 0x1c, 0xd6, 0xc7, 0x82, 0xc3,
|
||||
0x33, 0x03, 0xf1, 0x27, 0x5e, 0x14, 0xf8, 0x23, 0xe2, 0xb3, 0x6c, 0x66, 0xb8, 0xac, 0x59, 0xd8,
|
||||
0x94, 0x43, 0x5f, 0x84, 0x65, 0xe6, 0x44, 0x3d, 0xc2, 0x30, 0x99, 0x78, 0x34, 0x0e, 0xe4, 0x5a,
|
||||
0xfb, 0x69, 0xf5, 0xe5, 0xf2, 0x6e, 0x8a, 0x8b, 0x33, 0xd2, 0xe8, 0xb7, 0x16, 0x3c, 0xe3, 0x06,
|
||||
0xa3, 0x30, 0xf0, 0x89, 0xcf, 0x76, 0x9c, 0xc8, 0x19, 0x11, 0x46, 0xa2, 0x9b, 0x13, 0x12, 0x45,
|
||||
0x5e, 0x97, 0xd0, 0x46, 0x59, 0x78, 0xf7, 0xfa, 0x1c, 0xde, 0xdd, 0x98, 0xd1, 0xde, 0x7e, 0x56,
|
||||
0x19, 0xf7, 0xcc, 0xc6, 0xd1, 0xc8, 0xf8, 0x3f, 0x99, 0x85, 0xce, 0x43, 0x7d, 0xe2, 0x0c, 0xc7,
|
||||
0x84, 0x5e, 0xf1, 0x86, 0x84, 0x36, 0x2a, 0xba, 0x08, 0xbc, 0xa2, 0xc9, 0xd8, 0x94, 0xb1, 0x7f,
|
||||
0x5f, 0x48, 0x85, 0x68, 0x27, 0xce, 0x3b, 0x62, 0x2f, 0x55, 0x80, 0xe6, 0x95, 0x77, 0x84, 0x4e,
|
||||
0xe3, 0x74, 0xc9, 0xc2, 0xa4, 0xb0, 0xd0, 0x77, 0x2c, 0x51, 0x05, 0xe2, 0x53, 0xa9, 0x72, 0xec,
|
||||
0x23, 0xa8, 0x48, 0x66, 0x61, 0x89, 0x89, 0xd8, 0x84, 0xe6, 0x21, 0x1c, 0xca, 0xba, 0xaa, 0x22,
|
||||
0x2e, 0x09, 0x61, 0x55, 0x6e, 0x71, 0xcc, 0xb7, 0x7f, 0x5e, 0x49, 0x9f, 0x01, 0x99, 0x43, 0x7f,
|
||||
0x6c, 0xc1, 0x69, 0xbe, 0x51, 0x4e, 0xe4, 0xd1, 0xc0, 0xc7, 0x84, 0x8e, 0x87, 0x4c, 0x39, 0x73,
|
||||
0x7b, 0xce, 0xa0, 0x31, 0x55, 0xb6, 0x1b, 0xca, 0xae, 0xd3, 0x59, 0x0e, 0x9e, 0x81, 0x47, 0x0c,
|
||||
0x16, 0xfa, 0x1e, 0x65, 0x41, 0x34, 0x55, 0xc9, 0x61, 0x9e, 0xee, 0x6b, 0x93, 0x84, 0xc3, 0x60,
|
||||
0xca, 0xcf, 0xda, 0x96, 0xbf, 0x17, 0x68, 0xff, 0x5c, 0x95, 0x08, 0x38, 0x86, 0x42, 0xdf, 0xb4,
|
||||
0x00, 0xc2, 0x38, 0x52, 0x79, 0x21, 0x7b, 0x04, 0x07, 0x27, 0xa9, 0xd9, 0x09, 0x89, 0x62, 0x03,
|
||||
0x14, 0x05, 0x50, 0xe9, 0x13, 0x67, 0xc8, 0xfa, 0xaa, 0x9c, 0xbd, 0x38, 0x07, 0xfc, 0x55, 0xa1,
|
||||
0x28, 0x5b, 0x42, 0x25, 0x15, 0x2b, 0x18, 0xf4, 0x6d, 0x0b, 0x96, 0x93, 0xea, 0xc6, 0x65, 0x49,
|
||||
0xa3, 0x3c, 0x77, 0xc3, 0x7b, 0x33, 0xa5, 0xb0, 0x8d, 0x78, 0x1a, 0x4b, 0xd3, 0x70, 0x06, 0x14,
|
||||
0x7d, 0xcb, 0x02, 0x70, 0xe3, 0x6a, 0x2a, 0xf3, 0x41, 0xfd, 0xc2, 0xcd, 0x7c, 0x4e, 0x54, 0x52,
|
||||
0xa5, 0xb5, 0xfb, 0x13, 0x12, 0xc5, 0x06, 0xac, 0xfd, 0xae, 0x05, 0x4f, 0x19, 0x1f, 0x7e, 0xd9,
|
||||
0x61, 0x6e, 0xff, 0xf2, 0x84, 0xa7, 0xe9, 0xed, 0x54, 0x7d, 0xff, 0x8c, 0x59, 0xdf, 0xdf, 0xdf,
|
||||
0x5f, 0xfb, 0xe8, 0x51, 0x13, 0xcd, 0x1d, 0xae, 0xa1, 0x29, 0x54, 0x18, 0xad, 0xc0, 0x9b, 0x50,
|
||||
0x37, 0x6c, 0x56, 0xe9, 0x23, 0xaf, 0x02, 0x98, 0xe4, 0x0c, 0x83, 0x88, 0x4d, 0x3c, 0xfb, 0x2f,
|
||||
0x05, 0x58, 0xd8, 0x18, 0x8e, 0x29, 0x23, 0xd1, 0x89, 0x1b, 0x8a, 0x75, 0x28, 0xf1, 0x66, 0x21,
|
||||
0x5b, 0xff, 0x78, 0x2f, 0x81, 0x05, 0x07, 0x85, 0x50, 0x71, 0x03, 0x7f, 0xcf, 0xeb, 0xa9, 0x16,
|
||||
0xf0, 0xea, 0x3c, 0x27, 0x47, 0x5a, 0xb7, 0x21, 0xf4, 0x69, 0x9b, 0xe4, 0x3b, 0x56, 0x38, 0xe8,
|
||||
0x87, 0x16, 0xac, 0xb8, 0x81, 0xef, 0x13, 0x57, 0x07, 0x6f, 0x69, 0xee, 0x76, 0x77, 0x23, 0xad,
|
||||
0xb1, 0xfd, 0x01, 0x85, 0xbe, 0x92, 0x61, 0xe0, 0x2c, 0xb6, 0xfd, 0x9b, 0x02, 0x2c, 0xa5, 0x2c,
|
||||
0x47, 0xcf, 0x41, 0x75, 0x4c, 0x49, 0x24, 0x3c, 0x27, 0xfd, 0x9b, 0x74, 0x44, 0x2f, 0x2b, 0x3a,
|
||||
0x4e, 0x24, 0xb8, 0x74, 0xe8, 0x50, 0x7a, 0x27, 0x88, 0xba, 0xca, 0xcf, 0x89, 0xf4, 0x8e, 0xa2,
|
||||
0xe3, 0x44, 0x82, 0xf7, 0x1b, 0xb7, 0x88, 0x13, 0x91, 0x68, 0x37, 0x18, 0x90, 0x99, 0x49, 0xa4,
|
||||
0xad, 0x59, 0xd8, 0x94, 0x13, 0x4e, 0x63, 0x43, 0xba, 0x31, 0xf4, 0x88, 0xcf, 0xa4, 0x99, 0x39,
|
||||
0x38, 0x6d, 0xf7, 0x5a, 0xc7, 0xd4, 0xa8, 0x9d, 0x96, 0x61, 0xe0, 0x2c, 0xb6, 0xfd, 0x67, 0x0b,
|
||||
0xea, 0xca, 0x69, 0x8f, 0xa1, 0xe9, 0xec, 0xa5, 0x9b, 0xce, 0xf6, 0xfc, 0x31, 0x7a, 0x44, 0xc3,
|
||||
0xf9, 0xab, 0x22, 0xcc, 0x54, 0x3a, 0xf4, 0x3a, 0xcf, 0x71, 0x9c, 0x46, 0xba, 0x97, 0xe2, 0x22,
|
||||
0xfb, 0xf1, 0x93, 0xad, 0x6e, 0xd7, 0x1b, 0x11, 0x33, 0x7d, 0xc5, 0x5a, 0xb0, 0xa1, 0x11, 0xdd,
|
||||
0xb5, 0x34, 0xc0, 0x6e, 0xa0, 0xf2, 0x4a, 0xbe, 0x2d, 0xd1, 0x8c, 0x09, 0xbb, 0x01, 0x36, 0x30,
|
||||
0xd1, 0xe7, 0x92, 0x41, 0xb0, 0x2c, 0x02, 0xd2, 0x4e, 0x8f, 0x6e, 0xef, 0xa7, 0x1a, 0x80, 0xcc,
|
||||
0x38, 0x37, 0x85, 0x5a, 0x44, 0xe2, 0x6b, 0x01, 0x59, 0x01, 0xe6, 0x49, 0x22, 0x58, 0xe9, 0x92,
|
||||
0xc7, 0x38, 0x19, 0x7f, 0x62, 0x32, 0xc5, 0x1a, 0xcd, 0xfe, 0x81, 0x05, 0x68, 0xb6, 0x5c, 0xf3,
|
||||
0x31, 0x2a, 0x69, 0x62, 0xd5, 0x01, 0x4e, 0xf4, 0x24, 0xe2, 0x58, 0xcb, 0x9c, 0x20, 0x4d, 0x3e,
|
||||
0x0b, 0x65, 0xd1, 0xd4, 0xaa, 0x03, 0x9b, 0x44, 0x8f, 0x68, 0x7b, 0xb1, 0xe4, 0xd9, 0x7f, 0xb4,
|
||||
0x20, 0x9b, 0x6e, 0x44, 0xa6, 0x96, 0x9e, 0xcd, 0x66, 0xea, 0xb4, 0x17, 0x4f, 0x3e, 0x67, 0xa2,
|
||||
0xd7, 0xa0, 0xee, 0x30, 0x46, 0x46, 0x21, 0x13, 0x01, 0x59, 0x7c, 0xe0, 0x80, 0x5c, 0xe6, 0x91,
|
||||
0x70, 0x3d, 0xe8, 0x7a, 0x7b, 0x9e, 0x08, 0x46, 0x53, 0x9d, 0xfd, 0x5e, 0x11, 0x96, 0xd3, 0xcd,
|
||||
0x17, 0x1a, 0x43, 0x45, 0x34, 0x3b, 0xf2, 0xd6, 0x27, 0xf7, 0xee, 0x2a, 0x71, 0x89, 0x20, 0x51,
|
||||
0xac, 0xc0, 0x78, 0x62, 0x8d, 0xe2, 0xe9, 0x2a, 0x93, 0x58, 0x93, 0xb9, 0x2a, 0x91, 0x38, 0x76,
|
||||
0xa2, 0x2a, 0xfe, 0x6f, 0x4e, 0x54, 0xaf, 0x03, 0x74, 0x85, 0xb7, 0xc5, 0x5e, 0x96, 0x1e, 0x3e,
|
||||
0xb9, 0x6c, 0x26, 0x5a, 0xb0, 0xa1, 0x11, 0x9d, 0x85, 0x82, 0xd7, 0x15, 0xa7, 0xba, 0xd8, 0x06,
|
||||
0x25, 0x5b, 0xd8, 0xda, 0xc4, 0x05, 0xaf, 0x6b, 0x53, 0x58, 0x34, 0xbb, 0xcd, 0x13, 0xc7, 0xea,
|
||||
0xe7, 0x61, 0x49, 0x3e, 0x6d, 0x12, 0xe6, 0x78, 0x43, 0xaa, 0x76, 0xe7, 0x29, 0x25, 0xbe, 0xd4,
|
||||
0x31, 0x99, 0x38, 0x2d, 0x6b, 0xff, 0xac, 0x00, 0x70, 0x35, 0x08, 0x06, 0x0a, 0x33, 0x3e, 0x7a,
|
||||
0xd6, 0x91, 0x47, 0x6f, 0x1d, 0x4a, 0x03, 0xcf, 0xef, 0x66, 0x0f, 0xe7, 0xb6, 0xe7, 0x77, 0xb1,
|
||||
0xe0, 0xa0, 0x0b, 0x00, 0x4e, 0xe8, 0xbd, 0x42, 0x22, 0xaa, 0x2f, 0xf7, 0x12, 0xbf, 0x5c, 0xda,
|
||||
0xd9, 0x52, 0x1c, 0x6c, 0x48, 0xa1, 0xe7, 0x54, 0x67, 0x28, 0xc7, 0xf6, 0x46, 0xa6, 0x33, 0xac,
|
||||
0x72, 0x0b, 0x8d, 0xd6, 0xef, 0x62, 0x26, 0x3f, 0xae, 0xcf, 0xe4, 0x47, 0xdd, 0x29, 0xef, 0xf4,
|
||||
0x1d, 0x4a, 0x0e, 0x3b, 0xd7, 0x95, 0x63, 0xee, 0x8f, 0xfe, 0x69, 0x81, 0xbe, 0xbd, 0x42, 0x7b,
|
||||
0x50, 0xa2, 0x53, 0xdf, 0x55, 0xf5, 0x66, 0x9e, 0x8c, 0xda, 0x99, 0xfa, 0xae, 0xbe, 0x24, 0xab,
|
||||
0x8a, 0x3b, 0xc0, 0xa9, 0xef, 0x62, 0xa1, 0x1f, 0x4d, 0xa0, 0x1a, 0x05, 0xc3, 0xe1, 0x2d, 0xc7,
|
||||
0x1d, 0xe4, 0x50, 0x7a, 0xb0, 0x52, 0xa5, 0xf1, 0x16, 0xc5, 0x79, 0x55, 0x64, 0x9c, 0x60, 0xd9,
|
||||
0xbf, 0x2e, 0x43, 0x66, 0xba, 0x40, 0x63, 0xf3, 0x62, 0xd0, 0xca, 0xf1, 0x62, 0x30, 0xc9, 0xfe,
|
||||
0x87, 0x5d, 0x0e, 0xa2, 0x17, 0xa0, 0x1c, 0xf2, 0x3d, 0x53, 0x11, 0xb6, 0x16, 0xe7, 0x76, 0xb1,
|
||||
0x91, 0x87, 0x6c, 0xad, 0x94, 0x36, 0x77, 0xb6, 0x78, 0x4c, 0xc6, 0xfe, 0x06, 0x00, 0xf7, 0xb5,
|
||||
0x1a, 0xd3, 0xe5, 0x21, 0xbf, 0x91, 0xd7, 0x8e, 0xaa, 0x49, 0x5d, 0x24, 0xf5, 0x4e, 0x82, 0x82,
|
||||
0x0d, 0x44, 0xf4, 0x3d, 0x0b, 0x96, 0x63, 0xc7, 0x2b, 0x23, 0xca, 0x8f, 0xc4, 0x08, 0x31, 0x33,
|
||||
0xe2, 0x14, 0x12, 0xce, 0x20, 0xa3, 0xaf, 0x40, 0x8d, 0x32, 0x27, 0x92, 0xc5, 0xab, 0xf2, 0xc0,
|
||||
0x09, 0x2f, 0xd9, 0xcb, 0x4e, 0xac, 0x04, 0x6b, 0x7d, 0xe8, 0x55, 0x80, 0x3d, 0xcf, 0xf7, 0x68,
|
||||
0x5f, 0x68, 0x5f, 0x78, 0xb8, 0xd2, 0x78, 0x25, 0xd1, 0x80, 0x0d, 0x6d, 0xf6, 0x5f, 0x0b, 0x00,
|
||||
0xe2, 0x2f, 0x87, 0x27, 0x2e, 0x1e, 0xd6, 0xa1, 0x14, 0x91, 0x30, 0xc8, 0x66, 0x2e, 0x2e, 0x81,
|
||||
0x05, 0x27, 0x35, 0x47, 0x14, 0x1e, 0x68, 0x8e, 0x28, 0x1e, 0x3b, 0x47, 0xf0, 0x1c, 0x4c, 0xfb,
|
||||
0x3b, 0x91, 0x37, 0x71, 0x18, 0xd9, 0x26, 0x53, 0x95, 0xc8, 0x74, 0x0e, 0xee, 0x5c, 0xd5, 0x4c,
|
||||
0x9c, 0x96, 0x3d, 0x74, 0x04, 0x2b, 0xff, 0x17, 0x47, 0xb0, 0x77, 0x2c, 0x58, 0xd6, 0x9e, 0xfd,
|
||||
0xff, 0xfa, 0x8f, 0xa6, 0xed, 0x3e, 0x62, 0xa6, 0xf8, 0x97, 0x05, 0x2b, 0x71, 0xf7, 0xaa, 0x8a,
|
||||
0x35, 0x12, 0x41, 0x41, 0x08, 0x29, 0xbc, 0x24, 0x10, 0x42, 0x5c, 0x39, 0x70, 0x42, 0x48, 0x48,
|
||||
0x88, 0x13, 0x12, 0x07, 0x38, 0x20, 0x1f, 0x73, 0x00, 0x11, 0x05, 0xb4, 0xc2, 0x9b, 0x4b, 0x24,
|
||||
0x0e, 0xdc, 0x73, 0x42, 0xf5, 0xe8, 0xae, 0xea, 0x9e, 0x5d, 0x76, 0xed, 0x69, 0x1b, 0x72, 0xeb,
|
||||
0xfe, 0xff, 0xbf, 0xff, 0xef, 0xaf, 0xbf, 0xfe, 0xfa, 0x1f, 0xd5, 0xb0, 0xd5, 0xf3, 0x58, 0x7f,
|
||||
0x7c, 0xab, 0xe9, 0x06, 0xa3, 0x96, 0x13, 0xf5, 0x82, 0x30, 0x0a, 0x6e, 0x8b, 0x87, 0x67, 0xdd,
|
||||
0x6e, 0x2b, 0x1c, 0xf4, 0x5a, 0x4e, 0xe8, 0xd1, 0x96, 0x13, 0x86, 0x43, 0xcf, 0x75, 0x98, 0x17,
|
||||
0xf8, 0xad, 0xc9, 0x79, 0x67, 0x18, 0xf6, 0x9d, 0xf3, 0xad, 0x1e, 0xf1, 0x49, 0xe4, 0x30, 0xd2,
|
||||
0x6d, 0x86, 0x51, 0xc0, 0x02, 0xf4, 0x79, 0xad, 0xaa, 0x19, 0xab, 0x12, 0x0f, 0x5f, 0x77, 0xbb,
|
||||
0xcd, 0x70, 0xd0, 0x6b, 0x72, 0x55, 0x4d, 0x43, 0x55, 0x33, 0x56, 0x75, 0xf6, 0x59, 0xc3, 0x8a,
|
||||
0x5e, 0xd0, 0x0b, 0x5a, 0x42, 0xe3, 0xad, 0xf1, 0x9e, 0x78, 0x13, 0x2f, 0xe2, 0x49, 0x22, 0x9d,
|
||||
0xfd, 0xcc, 0xe0, 0x22, 0x6d, 0x7a, 0x01, 0xb7, 0x6d, 0xe4, 0xb8, 0x7d, 0xcf, 0x27, 0xd1, 0x54,
|
||||
0x1b, 0x3b, 0x22, 0xcc, 0x69, 0x4d, 0x66, 0xec, 0x3b, 0xdb, 0x3a, 0xea, 0xab, 0x68, 0xec, 0x33,
|
||||
0x6f, 0x44, 0x66, 0x3e, 0xf8, 0xec, 0x71, 0x1f, 0x50, 0xb7, 0x4f, 0x46, 0xce, 0xcc, 0x77, 0x9f,
|
||||
0x3e, 0xea, 0xbb, 0x31, 0xf3, 0x86, 0x2d, 0xcf, 0x67, 0x94, 0x45, 0xd9, 0x8f, 0xec, 0xbf, 0x5b,
|
||||
0x00, 0x97, 0xc2, 0x70, 0x27, 0x0a, 0x6e, 0x13, 0x97, 0xa1, 0x6f, 0x40, 0x95, 0xaf, 0xa3, 0xeb,
|
||||
0x30, 0xa7, 0x61, 0xad, 0x5b, 0xe7, 0xea, 0x17, 0x3e, 0xd5, 0x94, 0x6a, 0x9b, 0xa6, 0x5a, 0xed,
|
||||
0x57, 0x2e, 0xdd, 0x9c, 0x9c, 0x6f, 0xde, 0xbc, 0xc5, 0xbf, 0xbf, 0x4e, 0x98, 0xd3, 0x46, 0x77,
|
||||
0xf7, 0xd7, 0x4e, 0x1d, 0xec, 0xaf, 0x81, 0xa6, 0xe1, 0x44, 0x2b, 0x1a, 0x40, 0x89, 0x86, 0xc4,
|
||||
0x6d, 0x14, 0x84, 0xf6, 0xad, 0xe6, 0x03, 0xef, 0x5e, 0x53, 0x9b, 0xdd, 0x09, 0x89, 0xdb, 0x5e,
|
||||
0x54, 0xb0, 0x25, 0xfe, 0x86, 0x05, 0x88, 0xfd, 0x8e, 0x05, 0xcb, 0x5a, 0xec, 0x9a, 0x47, 0x19,
|
||||
0x7a, 0x65, 0x66, 0x85, 0xcd, 0x93, 0xad, 0x90, 0x7f, 0x2d, 0xd6, 0x77, 0x5a, 0x01, 0x55, 0x63,
|
||||
0x8a, 0xb1, 0xba, 0xdb, 0x50, 0xf6, 0x18, 0x19, 0xd1, 0x46, 0x61, 0xbd, 0x78, 0xae, 0x7e, 0xe1,
|
||||
0x72, 0x2e, 0xcb, 0x6b, 0x2f, 0x29, 0xc4, 0xf2, 0x16, 0xd7, 0x8d, 0x25, 0x84, 0xfd, 0x66, 0xc1,
|
||||
0x5c, 0x1c, 0x5f, 0x35, 0x3a, 0x0f, 0x75, 0x1a, 0x8c, 0x23, 0x97, 0x60, 0x12, 0x06, 0xb4, 0x61,
|
||||
0xad, 0x17, 0xcf, 0xd5, 0xda, 0x2b, 0x07, 0xfb, 0x6b, 0xf5, 0x8e, 0x26, 0x63, 0x53, 0x06, 0xfd,
|
||||
0xc0, 0x82, 0xc5, 0x2e, 0xa1, 0xcc, 0xf3, 0x05, 0x7e, 0x6c, 0xf9, 0x57, 0xe6, 0xb3, 0x3c, 0x26,
|
||||
0x6e, 0x6a, 0xcd, 0xed, 0xc7, 0xd5, 0x2a, 0x16, 0x0d, 0x22, 0xc5, 0x29, 0x70, 0xf4, 0x1c, 0xd4,
|
||||
0xbb, 0x84, 0xba, 0x91, 0x17, 0xf2, 0xf7, 0x46, 0x71, 0xdd, 0x3a, 0x57, 0x6b, 0x3f, 0xa6, 0x3e,
|
||||
0xac, 0x6f, 0x6a, 0x16, 0x36, 0xe5, 0xec, 0x3f, 0x17, 0xa1, 0x6e, 0xa0, 0x3e, 0x82, 0x30, 0x1e,
|
||||
0xa6, 0xc2, 0xf8, 0x85, 0x7c, 0xbc, 0x75, 0x54, 0x1c, 0x23, 0x06, 0x15, 0xca, 0x1c, 0x36, 0xa6,
|
||||
0xc2, 0x23, 0xf5, 0x0b, 0xd7, 0x72, 0xc2, 0x13, 0x3a, 0xdb, 0xcb, 0x0a, 0xb1, 0x22, 0xdf, 0xb1,
|
||||
0xc2, 0x42, 0xaf, 0x41, 0x2d, 0x08, 0x79, 0xb6, 0xe0, 0x5b, 0x51, 0x12, 0xc0, 0x9b, 0x73, 0x00,
|
||||
0xdf, 0x8c, 0x75, 0xb5, 0x97, 0x0e, 0xf6, 0xd7, 0x6a, 0xc9, 0x2b, 0xd6, 0x28, 0xb6, 0x0b, 0x8f,
|
||||
0x1b, 0xf6, 0x6d, 0x04, 0x7e, 0xd7, 0x13, 0x1b, 0xba, 0x0e, 0x25, 0x36, 0x0d, 0x89, 0xd8, 0xcc,
|
||||
0x9a, 0x76, 0xd1, 0xee, 0x34, 0x24, 0x58, 0x70, 0xd0, 0x27, 0x60, 0x61, 0x44, 0x28, 0x75, 0x7a,
|
||||
0x44, 0xec, 0x49, 0xad, 0xbd, 0xa2, 0x84, 0x16, 0xae, 0x4b, 0x32, 0x8e, 0xf9, 0xf6, 0x6b, 0xf0,
|
||||
0xe4, 0xe1, 0x21, 0x8a, 0x3e, 0x06, 0x15, 0x4a, 0xa2, 0x09, 0x89, 0x14, 0x90, 0xf6, 0x8c, 0xa0,
|
||||
0x62, 0xc5, 0x45, 0x2d, 0xa8, 0xf9, 0xce, 0x88, 0xd0, 0xd0, 0x71, 0x63, 0xb8, 0x33, 0x4a, 0xb4,
|
||||
0x76, 0x23, 0x66, 0x60, 0x2d, 0x63, 0xff, 0xc3, 0x82, 0x15, 0x03, 0xf3, 0x11, 0x64, 0xa2, 0x41,
|
||||
0x3a, 0x13, 0x5d, 0xc9, 0x27, 0x62, 0x8e, 0x48, 0x45, 0x7f, 0x2c, 0xc2, 0x19, 0x33, 0xae, 0x44,
|
||||
0x7e, 0xe1, 0x5b, 0x12, 0x91, 0x30, 0x78, 0x11, 0x5f, 0x53, 0xee, 0x4c, 0xb6, 0x04, 0x4b, 0x32,
|
||||
0x8e, 0xf9, 0x7c, 0x7f, 0x43, 0x87, 0xf5, 0x95, 0x2f, 0x93, 0xfd, 0xdd, 0x71, 0x58, 0x1f, 0x0b,
|
||||
0x0e, 0xcf, 0x0c, 0xc4, 0x9f, 0x78, 0x51, 0xe0, 0x8f, 0x88, 0xcf, 0xb2, 0x99, 0xe1, 0xb2, 0x66,
|
||||
0x61, 0x53, 0x0e, 0x7d, 0x19, 0x96, 0x99, 0x13, 0xf5, 0x08, 0xc3, 0x64, 0xe2, 0xd1, 0x38, 0x90,
|
||||
0x6b, 0xed, 0x27, 0xd5, 0x97, 0xcb, 0xbb, 0x29, 0x2e, 0xce, 0x48, 0xa3, 0xdf, 0x59, 0xf0, 0x94,
|
||||
0x1b, 0x8c, 0xc2, 0xc0, 0x27, 0x3e, 0xdb, 0x71, 0x22, 0x67, 0x44, 0x18, 0x89, 0x6e, 0x4e, 0x48,
|
||||
0x14, 0x79, 0x5d, 0x42, 0x1b, 0x65, 0xe1, 0xdd, 0xeb, 0x73, 0x78, 0x77, 0x63, 0x46, 0x7b, 0xfb,
|
||||
0x69, 0x65, 0xdc, 0x53, 0x1b, 0x47, 0x23, 0xe3, 0xff, 0x66, 0x16, 0x2f, 0x04, 0x13, 0x67, 0x38,
|
||||
0x26, 0xf4, 0x8a, 0x37, 0x24, 0xb4, 0x51, 0xd1, 0x85, 0xe0, 0x25, 0x4d, 0xc6, 0xa6, 0x8c, 0xfd,
|
||||
0x87, 0x42, 0x2a, 0x44, 0x3b, 0x71, 0xde, 0x11, 0x7b, 0xa9, 0x02, 0x34, 0xaf, 0xbc, 0x23, 0x74,
|
||||
0x1a, 0xa7, 0x4b, 0xd6, 0x23, 0x85, 0x85, 0xde, 0xb4, 0x44, 0x15, 0x88, 0x4f, 0xa5, 0xca, 0xb1,
|
||||
0x0f, 0xa1, 0x22, 0x99, 0x85, 0x25, 0x26, 0x62, 0x13, 0x9a, 0x87, 0x70, 0x28, 0xeb, 0xab, 0x8a,
|
||||
0xb8, 0x24, 0x84, 0x55, 0xd9, 0xc5, 0x31, 0xdf, 0xfe, 0x45, 0x25, 0x7d, 0x06, 0x64, 0x0e, 0xfd,
|
||||
0x89, 0x05, 0xa7, 0xf9, 0x46, 0x39, 0x91, 0x47, 0x03, 0x1f, 0x13, 0x3a, 0x1e, 0x32, 0xe5, 0xcc,
|
||||
0xed, 0x39, 0x83, 0xc6, 0x54, 0xd9, 0x6e, 0x28, 0xbb, 0x4e, 0x67, 0x39, 0x78, 0x06, 0x1e, 0x31,
|
||||
0x58, 0xe8, 0x7b, 0x94, 0x05, 0xd1, 0x54, 0x25, 0x87, 0x79, 0xba, 0xb0, 0x4d, 0x12, 0x0e, 0x83,
|
||||
0x29, 0x3f, 0x6b, 0x5b, 0xfe, 0x5e, 0xa0, 0xfd, 0x73, 0x55, 0x22, 0xe0, 0x18, 0x0a, 0x7d, 0xdb,
|
||||
0x02, 0x08, 0xe3, 0x48, 0xe5, 0x85, 0xec, 0x21, 0x1c, 0x9c, 0xa4, 0x66, 0x27, 0x24, 0x8a, 0x0d,
|
||||
0x50, 0x14, 0x40, 0xa5, 0x4f, 0x9c, 0x21, 0xeb, 0xab, 0x72, 0xf6, 0xfc, 0x1c, 0xf0, 0x57, 0x85,
|
||||
0xa2, 0x6c, 0x09, 0x95, 0x54, 0xac, 0x60, 0xd0, 0x77, 0x2d, 0x58, 0x4e, 0xaa, 0x1b, 0x97, 0x25,
|
||||
0x8d, 0xf2, 0xdc, 0x8d, 0xef, 0xcd, 0x94, 0xc2, 0x36, 0xe2, 0x69, 0x2c, 0x4d, 0xc3, 0x19, 0x50,
|
||||
0xf4, 0x1d, 0x0b, 0xc0, 0x8d, 0xab, 0xa9, 0xcc, 0x07, 0xf5, 0x0b, 0x37, 0xf3, 0x39, 0x51, 0x49,
|
||||
0x95, 0xd6, 0xee, 0x4f, 0x48, 0x14, 0x1b, 0xb0, 0xf6, 0xbb, 0x16, 0x3c, 0x61, 0x7c, 0xf8, 0x55,
|
||||
0x87, 0xb9, 0xfd, 0xcb, 0x13, 0x9e, 0xa6, 0xb7, 0x53, 0xf5, 0xfd, 0x73, 0x66, 0x7d, 0x7f, 0x7f,
|
||||
0x7f, 0xed, 0xe3, 0x47, 0x4d, 0x36, 0x77, 0xb8, 0x86, 0xa6, 0x50, 0x61, 0xb4, 0x02, 0xaf, 0x43,
|
||||
0xdd, 0xb0, 0x59, 0xa5, 0x8f, 0xbc, 0x0a, 0x60, 0x92, 0x33, 0x0c, 0x22, 0x36, 0xf1, 0xec, 0xbf,
|
||||
0x16, 0x60, 0x61, 0x63, 0x38, 0xa6, 0x8c, 0x44, 0x27, 0x6e, 0x28, 0xd6, 0xa1, 0xc4, 0x9b, 0x85,
|
||||
0x6c, 0xfd, 0xe3, 0xbd, 0x04, 0x16, 0x1c, 0x14, 0x42, 0xc5, 0x0d, 0xfc, 0x3d, 0xaf, 0xa7, 0x5a,
|
||||
0xc0, 0xab, 0xf3, 0x9c, 0x1c, 0x69, 0xdd, 0x86, 0xd0, 0xa7, 0x6d, 0x92, 0xef, 0x58, 0xe1, 0xa0,
|
||||
0x1f, 0x59, 0xb0, 0xe2, 0x06, 0xbe, 0x4f, 0x5c, 0x1d, 0xbc, 0xa5, 0xb9, 0xdb, 0xdd, 0x8d, 0xb4,
|
||||
0xc6, 0xf6, 0x87, 0x14, 0xfa, 0x4a, 0x86, 0x81, 0xb3, 0xd8, 0xf6, 0x6f, 0x0b, 0xb0, 0x94, 0xb2,
|
||||
0x1c, 0x3d, 0x03, 0xd5, 0x31, 0x25, 0x91, 0xf0, 0x9c, 0xf4, 0x6f, 0xd2, 0x11, 0xbd, 0xa8, 0xe8,
|
||||
0x38, 0x91, 0xe0, 0xd2, 0xa1, 0x43, 0xe9, 0x9d, 0x20, 0xea, 0x2a, 0x3f, 0x27, 0xd2, 0x3b, 0x8a,
|
||||
0x8e, 0x13, 0x09, 0xde, 0x6f, 0xdc, 0x22, 0x4e, 0x44, 0xa2, 0xdd, 0x60, 0x40, 0x66, 0x26, 0x91,
|
||||
0xb6, 0x66, 0x61, 0x53, 0x4e, 0x38, 0x8d, 0x0d, 0xe9, 0xc6, 0xd0, 0x23, 0x3e, 0x93, 0x66, 0xe6,
|
||||
0xe0, 0xb4, 0xdd, 0x6b, 0x1d, 0x53, 0xa3, 0x76, 0x5a, 0x86, 0x81, 0xb3, 0xd8, 0xf6, 0x5f, 0x2c,
|
||||
0xa8, 0x2b, 0xa7, 0x3d, 0x82, 0xa6, 0xb3, 0x97, 0x6e, 0x3a, 0xdb, 0xf3, 0xc7, 0xe8, 0x11, 0x0d,
|
||||
0xe7, 0xaf, 0x8b, 0x30, 0x53, 0xe9, 0xd0, 0xab, 0x3c, 0xc7, 0x71, 0x1a, 0xe9, 0x5e, 0x8a, 0x8b,
|
||||
0xec, 0x27, 0x4f, 0xb6, 0xba, 0x5d, 0x6f, 0x44, 0xcc, 0xf4, 0x15, 0x6b, 0xc1, 0x86, 0x46, 0xf4,
|
||||
0x86, 0xa5, 0x01, 0x76, 0x03, 0x95, 0x57, 0xf2, 0x6d, 0x89, 0x66, 0x4c, 0xd8, 0x0d, 0xb0, 0x81,
|
||||
0x89, 0xbe, 0x90, 0x0c, 0x82, 0x65, 0x11, 0x90, 0x76, 0x7a, 0x74, 0x7b, 0x3f, 0xd5, 0x00, 0x64,
|
||||
0xc6, 0xb9, 0x29, 0xd4, 0x22, 0x22, 0x5b, 0xac, 0xb8, 0x02, 0xcc, 0x93, 0x44, 0xb0, 0xd2, 0x25,
|
||||
0x8f, 0x71, 0x32, 0xfe, 0xc4, 0x64, 0x8a, 0x35, 0x9a, 0xfd, 0x43, 0x0b, 0xd0, 0x6c, 0xb9, 0xe6,
|
||||
0x63, 0x54, 0xd2, 0xc4, 0xaa, 0x03, 0x9c, 0xe8, 0x49, 0xc4, 0xb1, 0x96, 0x39, 0x41, 0x9a, 0x7c,
|
||||
0x1a, 0xca, 0xa2, 0xa9, 0x55, 0x07, 0x36, 0x89, 0x1e, 0xd1, 0xf6, 0x62, 0xc9, 0xb3, 0xff, 0x64,
|
||||
0x41, 0x36, 0xdd, 0x88, 0x4c, 0x2d, 0x3d, 0x9b, 0xcd, 0xd4, 0x69, 0x2f, 0x9e, 0x7c, 0xce, 0x44,
|
||||
0xaf, 0x40, 0xdd, 0x61, 0x8c, 0x8c, 0x42, 0x26, 0x02, 0xb2, 0x78, 0xdf, 0x01, 0xb9, 0xcc, 0x23,
|
||||
0xe1, 0x7a, 0xd0, 0xf5, 0xf6, 0x3c, 0x11, 0x8c, 0xa6, 0x3a, 0xfb, 0xbd, 0x22, 0x2c, 0xa7, 0x9b,
|
||||
0x2f, 0x34, 0x86, 0x8a, 0x68, 0x76, 0xe4, 0xcd, 0x4f, 0xee, 0xdd, 0x55, 0xe2, 0x12, 0x41, 0xa2,
|
||||
0x58, 0x81, 0xf1, 0xc4, 0x1a, 0xc5, 0xd3, 0x55, 0x26, 0xb1, 0x26, 0x73, 0x55, 0x22, 0x71, 0xec,
|
||||
0x44, 0x55, 0xfc, 0xff, 0x9c, 0xa8, 0x5e, 0x05, 0xe8, 0x0a, 0x6f, 0x8b, 0xbd, 0x2c, 0x3d, 0x78,
|
||||
0x72, 0xd9, 0x4c, 0xb4, 0x60, 0x43, 0x23, 0x3a, 0x0b, 0x05, 0xaf, 0x2b, 0x4e, 0x75, 0xb1, 0x0d,
|
||||
0x4a, 0xb6, 0xb0, 0xb5, 0x89, 0x0b, 0x5e, 0xd7, 0xa6, 0xb0, 0x68, 0x76, 0x9b, 0x27, 0x8e, 0xd5,
|
||||
0x2f, 0xc2, 0x92, 0x7c, 0xda, 0x24, 0xcc, 0xf1, 0x86, 0x54, 0xed, 0xce, 0x13, 0x4a, 0x7c, 0xa9,
|
||||
0x63, 0x32, 0x71, 0x5a, 0xd6, 0xfe, 0x79, 0x01, 0xe0, 0x6a, 0x10, 0x0c, 0x14, 0x66, 0x7c, 0xf4,
|
||||
0xac, 0x23, 0x8f, 0xde, 0x3a, 0x94, 0x06, 0x9e, 0xdf, 0xcd, 0x1e, 0xce, 0x6d, 0xcf, 0xef, 0x62,
|
||||
0xc1, 0x41, 0x17, 0x00, 0x9c, 0xd0, 0x7b, 0x89, 0x44, 0x54, 0x5f, 0xee, 0x25, 0x7e, 0xb9, 0xb4,
|
||||
0xb3, 0xa5, 0x38, 0xd8, 0x90, 0x42, 0xcf, 0xa8, 0xce, 0x50, 0x8e, 0xed, 0x8d, 0x4c, 0x67, 0x58,
|
||||
0xe5, 0x16, 0x1a, 0xad, 0xdf, 0xc5, 0x4c, 0x7e, 0x5c, 0x9f, 0xc9, 0x8f, 0xba, 0x53, 0xde, 0xe9,
|
||||
0x3b, 0x94, 0x1c, 0x76, 0xae, 0x2b, 0xc7, 0xdc, 0x1f, 0xfd, 0xcb, 0x02, 0x7d, 0x7b, 0x85, 0xf6,
|
||||
0xa0, 0x44, 0xa7, 0xbe, 0xab, 0xea, 0xcd, 0x3c, 0x19, 0xb5, 0x33, 0xf5, 0x5d, 0x7d, 0x49, 0x56,
|
||||
0x15, 0x77, 0x80, 0x53, 0xdf, 0xc5, 0x42, 0x3f, 0x9a, 0x40, 0x35, 0x0a, 0x86, 0xc3, 0x5b, 0x8e,
|
||||
0x3b, 0xc8, 0xa1, 0xf4, 0x60, 0xa5, 0x4a, 0xe3, 0x2d, 0x8a, 0xf3, 0xaa, 0xc8, 0x38, 0xc1, 0xb2,
|
||||
0x7f, 0x53, 0x86, 0xcc, 0x74, 0x81, 0xc6, 0xe6, 0xc5, 0xa0, 0x95, 0xe3, 0xc5, 0x60, 0x92, 0xfd,
|
||||
0x0f, 0xbb, 0x1c, 0x44, 0xcf, 0x41, 0x39, 0xe4, 0x7b, 0xa6, 0x22, 0x6c, 0x2d, 0xce, 0xed, 0x62,
|
||||
0x23, 0x0f, 0xd9, 0x5a, 0x29, 0x6d, 0xee, 0x6c, 0xf1, 0x98, 0x8c, 0xfd, 0x2d, 0x00, 0xee, 0x6b,
|
||||
0x35, 0xa6, 0xcb, 0x43, 0x7e, 0x23, 0xaf, 0x1d, 0x55, 0x93, 0xba, 0x48, 0xea, 0x9d, 0x04, 0x05,
|
||||
0x1b, 0x88, 0xe8, 0xfb, 0x16, 0x2c, 0xc7, 0x8e, 0x57, 0x46, 0x94, 0x1f, 0x8a, 0x11, 0x62, 0x66,
|
||||
0xc4, 0x29, 0x24, 0x9c, 0x41, 0x46, 0x5f, 0x83, 0x1a, 0x65, 0x4e, 0x24, 0x8b, 0x57, 0xe5, 0xbe,
|
||||
0x13, 0x5e, 0xb2, 0x97, 0x9d, 0x58, 0x09, 0xd6, 0xfa, 0xd0, 0xcb, 0x00, 0x7b, 0x9e, 0xef, 0xd1,
|
||||
0xbe, 0xd0, 0xbe, 0xf0, 0x60, 0xa5, 0xf1, 0x4a, 0xa2, 0x01, 0x1b, 0xda, 0xec, 0xbf, 0x15, 0x00,
|
||||
0xc4, 0xcf, 0x0d, 0x4f, 0x5c, 0x3c, 0xac, 0x43, 0x29, 0x22, 0x61, 0x90, 0xcd, 0x5c, 0x5c, 0x02,
|
||||
0x0b, 0x4e, 0x6a, 0x8e, 0x28, 0xdc, 0xd7, 0x1c, 0x51, 0x3c, 0x76, 0x8e, 0xe0, 0x39, 0x98, 0xf6,
|
||||
0x77, 0x22, 0x6f, 0xe2, 0x30, 0xb2, 0x4d, 0xa6, 0x2a, 0x91, 0xe9, 0x1c, 0xdc, 0xb9, 0xaa, 0x99,
|
||||
0x38, 0x2d, 0x7b, 0xe8, 0x08, 0x56, 0xfe, 0x1f, 0x8e, 0x60, 0xef, 0x58, 0xb0, 0xac, 0x3d, 0xfb,
|
||||
0xc1, 0xfa, 0x9f, 0xa6, 0xed, 0x3e, 0x62, 0xa6, 0xf8, 0xb7, 0x05, 0x2b, 0x71, 0xf7, 0xaa, 0x8a,
|
||||
0x60, 0x2e, 0x55, 0x2f, 0xf5, 0xb3, 0xa0, 0x78, 0xfc, 0xcf, 0x02, 0x33, 0x61, 0x95, 0x8e, 0x49,
|
||||
0x58, 0x5f, 0xc8, 0xd4, 0xbb, 0x0f, 0xcd, 0xd4, 0x3b, 0x94, 0xf4, 0xe9, 0x53, 0xdf, 0x4d, 0xf7,
|
||||
0x07, 0xf6, 0x2f, 0x2d, 0x58, 0x8c, 0xd9, 0x37, 0x82, 0xae, 0xe8, 0x9e, 0xa9, 0x08, 0x32, 0x2b,
|
||||
0x58, 0x5f, 0xca, 0xd4, 0xbb, 0x8f, 0xcc, 0xd4, 0x3b, 0x94, 0xf4, 0xe9, 0x53, 0xdf, 0x4d, 0xf7,
|
||||
0x07, 0xf6, 0xaf, 0x2c, 0x58, 0x8c, 0xd9, 0x37, 0x82, 0xae, 0xe8, 0x9e, 0xa9, 0x08, 0x32, 0x2b,
|
||||
0xdd, 0x3d, 0xcb, 0x70, 0x90, 0x3c, 0x34, 0x86, 0xaa, 0xdb, 0xf7, 0x86, 0xdd, 0x88, 0xf8, 0x6a,
|
||||
0x5b, 0x5e, 0xcc, 0x61, 0x8c, 0xe0, 0xf8, 0x3a, 0x14, 0x36, 0x14, 0x00, 0x4e, 0xa0, 0xec, 0xdf,
|
||||
0x15, 0x61, 0x29, 0x35, 0x73, 0xf0, 0x11, 0x5d, 0xde, 0xd6, 0x77, 0x0c, 0x9b, 0x93, 0x11, 0x7d,
|
||||
0x5b, 0x9e, 0xcf, 0x61, 0x8c, 0xe0, 0xf8, 0x3a, 0x14, 0x36, 0x14, 0x00, 0x4e, 0xa0, 0xec, 0xdf,
|
||||
0x17, 0x61, 0x29, 0x35, 0x73, 0xf0, 0x11, 0x5d, 0xde, 0xd6, 0x77, 0x0c, 0x9b, 0x93, 0x11, 0x7d,
|
||||
0x57, 0xb3, 0xb0, 0x29, 0xc7, 0xf7, 0x63, 0xe8, 0x4d, 0xa4, 0x8e, 0xec, 0xcf, 0x9b, 0x6b, 0x31,
|
||||
0x03, 0x6b, 0x19, 0x63, 0xe8, 0x2a, 0x3e, 0xf0, 0xd0, 0xf5, 0x13, 0x0b, 0x90, 0x58, 0x02, 0xd7,
|
||||
0x03, 0x6b, 0x19, 0x63, 0xe8, 0x2a, 0xde, 0xf7, 0xd0, 0xf5, 0x53, 0x0b, 0x90, 0x58, 0x02, 0xd7,
|
||||
0x9c, 0xcc, 0x46, 0x8d, 0x52, 0xbe, 0x7e, 0x3b, 0xab, 0x2c, 0x42, 0x1b, 0x33, 0x50, 0xf8, 0x10,
|
||||
0x78, 0xe3, 0x1e, 0xb4, 0xfc, 0x58, 0xee, 0x41, 0xed, 0xaf, 0xc3, 0x99, 0x99, 0x8e, 0x43, 0xb5,
|
||||
0x78, 0xe3, 0x1e, 0xb4, 0xfc, 0x48, 0xee, 0x41, 0xed, 0x6f, 0xc2, 0x99, 0x99, 0x8e, 0x43, 0xb5,
|
||||
0xbc, 0xd6, 0x61, 0x2d, 0x2f, 0x8f, 0xc4, 0x30, 0x1a, 0xfb, 0x72, 0x83, 0xaa, 0x3a, 0x12, 0x77,
|
||||
0x38, 0x11, 0x4b, 0x1e, 0xef, 0x83, 0xbb, 0xd1, 0x14, 0x8f, 0x65, 0x2f, 0x59, 0xd5, 0xe8, 0x9b,
|
||||
0x82, 0x8a, 0x15, 0xd7, 0xfe, 0x6e, 0x01, 0x96, 0x52, 0x55, 0x30, 0x35, 0xb2, 0x58, 0xc7, 0x8e,
|
||||
0x2c, 0x79, 0x1a, 0x83, 0xde, 0x84, 0x45, 0x2a, 0x8e, 0x62, 0xe4, 0x30, 0xd2, 0x9b, 0xe6, 0x70,
|
||||
0x82, 0x8a, 0x15, 0xd7, 0xfe, 0x5e, 0x01, 0x96, 0x52, 0x55, 0x30, 0x35, 0xb2, 0x58, 0xc7, 0x8e,
|
||||
0x2c, 0x79, 0x1a, 0x83, 0x5e, 0x87, 0x45, 0x2a, 0x8e, 0x62, 0xe4, 0x30, 0xd2, 0x9b, 0xe6, 0x70,
|
||||
0x13, 0xdd, 0x31, 0xd4, 0xb5, 0x4f, 0x1f, 0xec, 0xaf, 0x2d, 0x9a, 0x14, 0x9c, 0x82, 0xb3, 0x7f,
|
||||
0x51, 0x80, 0x27, 0x0e, 0xe9, 0x08, 0xd0, 0x1d, 0xf3, 0x76, 0x40, 0x8e, 0x8f, 0x2f, 0xe5, 0x10,
|
||||
0x9e, 0x2a, 0x91, 0xca, 0x5f, 0xbe, 0x87, 0xdd, 0x0d, 0x3c, 0xe0, 0xf4, 0xb8, 0x07, 0xe5, 0x7e,
|
||||
0x59, 0x80, 0xc7, 0x0e, 0xe9, 0x08, 0xd0, 0x1d, 0xf3, 0x76, 0x40, 0x8e, 0x8f, 0x2f, 0xe4, 0x10,
|
||||
0x9e, 0x2a, 0x91, 0xca, 0x5f, 0xbe, 0x87, 0xdd, 0x0d, 0xdc, 0xe7, 0xf4, 0xb8, 0x07, 0xe5, 0x7e,
|
||||
0x10, 0x0c, 0xe2, 0x31, 0x71, 0x9e, 0x82, 0xa0, 0x87, 0x9b, 0x76, 0x8d, 0xef, 0x26, 0x7f, 0xa7,
|
||||
0x58, 0xaa, 0xb7, 0xdf, 0xb3, 0x20, 0xe5, 0x45, 0x34, 0x82, 0x32, 0xd7, 0x32, 0xcd, 0xe1, 0x4f,
|
||||
0x98, 0xa9, 0xf7, 0x12, 0xd7, 0x29, 0xf1, 0xc5, 0x23, 0x96, 0x28, 0xc8, 0x83, 0x12, 0x37, 0x44,
|
||||
0x75, 0xfa, 0xdb, 0x39, 0xa1, 0xf1, 0x25, 0xca, 0xc1, 0x82, 0x3f, 0x61, 0x01, 0x61, 0x5f, 0x84,
|
||||
0x33, 0x33, 0x16, 0xf1, 0x90, 0xdf, 0x0b, 0xe2, 0x1f, 0x7f, 0x46, 0xc8, 0x5f, 0xe1, 0x44, 0x2c,
|
||||
0x79, 0xbc, 0x7e, 0x9c, 0xce, 0xaa, 0x47, 0x3f, 0xb5, 0xe0, 0x0c, 0xcd, 0xea, 0x7b, 0x24, 0x5e,
|
||||
0xfb, 0xa0, 0x32, 0x6a, 0xd6, 0x7c, 0x3c, 0x6b, 0x01, 0xdf, 0xd1, 0xec, 0x75, 0x29, 0x8f, 0x3d,
|
||||
0x79, 0xbc, 0x7e, 0x9c, 0xce, 0xaa, 0x47, 0x3f, 0xb3, 0xe0, 0x0c, 0xcd, 0xea, 0x7b, 0x28, 0x5e,
|
||||
0xfb, 0xb0, 0x32, 0x6a, 0xd6, 0x7c, 0x3c, 0x6b, 0x01, 0xdf, 0xd1, 0xec, 0x75, 0x29, 0x8f, 0x3d,
|
||||
0xcf, 0xa7, 0xc4, 0x1d, 0x47, 0xf1, 0x42, 0x93, 0xd8, 0xdb, 0x52, 0x74, 0x9c, 0x48, 0xf0, 0xf1,
|
||||
0x55, 0x5e, 0xd7, 0xdf, 0xd0, 0x8d, 0x62, 0x32, 0xbe, 0x76, 0x12, 0x0e, 0x36, 0xa4, 0xd0, 0x39,
|
||||
0xa8, 0xba, 0x24, 0x62, 0x9b, 0xbc, 0x3d, 0xe2, 0x79, 0x61, 0x51, 0xce, 0x59, 0x1b, 0x8a, 0x86,
|
||||
0x13, 0x2e, 0xfa, 0x30, 0x2c, 0x0c, 0xc8, 0x54, 0x08, 0x96, 0x84, 0x60, 0x9d, 0x57, 0xfc, 0x6d,
|
||||
0x13, 0x2e, 0xfa, 0x28, 0x2c, 0x0c, 0xc8, 0x54, 0x08, 0x96, 0x84, 0x60, 0x9d, 0x57, 0xfc, 0x6d,
|
||||
0x49, 0xc2, 0x31, 0x0f, 0xd9, 0x50, 0x71, 0x1d, 0x21, 0x55, 0x16, 0x52, 0x20, 0x6e, 0xee, 0x2f,
|
||||
0x09, 0x21, 0xc5, 0x69, 0x37, 0xef, 0xdd, 0x5f, 0x3d, 0xf5, 0xd6, 0xfd, 0xd5, 0x53, 0x6f, 0xdf,
|
||||
0x5f, 0x3d, 0x75, 0xf7, 0x60, 0xd5, 0xba, 0x77, 0xb0, 0x6a, 0xbd, 0x75, 0xb0, 0x6a, 0xbd, 0x7d,
|
||||
0xb0, 0x6a, 0xfd, 0xe3, 0x60, 0xd5, 0xfa, 0xd1, 0xbb, 0xab, 0xa7, 0x5e, 0xad, 0xc6, 0xae, 0xfd,
|
||||
0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x73, 0x59, 0x1b, 0x86, 0x27, 0x00, 0x00,
|
||||
0x09, 0x21, 0xc5, 0x69, 0x37, 0xef, 0xde, 0x5b, 0x3d, 0xf5, 0xd6, 0xbd, 0xd5, 0x53, 0x6f, 0xdf,
|
||||
0x5b, 0x3d, 0xf5, 0xc6, 0xc1, 0xaa, 0x75, 0xf7, 0x60, 0xd5, 0x7a, 0xeb, 0x60, 0xd5, 0x7a, 0xfb,
|
||||
0x60, 0xd5, 0xfa, 0xe7, 0xc1, 0xaa, 0xf5, 0xe3, 0x77, 0x57, 0x4f, 0xbd, 0x5c, 0x8d, 0x5d, 0xfb,
|
||||
0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf5, 0xd2, 0xa5, 0x7e, 0x8e, 0x27, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ message AppProjectList {
|
||||
// AppProjectSpec represents
|
||||
message AppProjectSpec {
|
||||
// SourceRepos contains list of git repository URLs which can be used for deployment
|
||||
repeated string sources = 1;
|
||||
repeated string sourceRepos = 1;
|
||||
|
||||
// Destinations contains list of destinations available for deployment
|
||||
repeated ApplicationDestination destinations = 2;
|
||||
|
||||
@@ -446,7 +446,7 @@ type AppProject struct {
|
||||
// AppProjectSpec represents
|
||||
type AppProjectSpec struct {
|
||||
// SourceRepos contains list of git repository URLs which can be used for deployment
|
||||
SourceRepos []string `json:"sources" protobuf:"bytes,1,name=destination"`
|
||||
SourceRepos []string `json:"sourceRepos" protobuf:"bytes,1,name=sourceRepos"`
|
||||
|
||||
// Destinations contains list of destinations available for deployment
|
||||
Destinations []ApplicationDestination `json:"destinations" protobuf:"bytes,2,name=destination"`
|
||||
|
||||
@@ -191,13 +191,20 @@ func generateManifests(appPath string, q *ManifestRequest) (*ManifestResponse, e
|
||||
var env *app.EnvironmentSpec
|
||||
var err error
|
||||
|
||||
appSourceType := identifyAppSourceType(appPath)
|
||||
appSourceType := IdentifyAppSourceTypeByAppDir(appPath)
|
||||
switch appSourceType {
|
||||
case AppSourceKsonnet:
|
||||
targetObjs, params, env, err = ksShow(appPath, q.Environment, q.ComponentParameterOverrides)
|
||||
case AppSourceHelm:
|
||||
h := helm.NewHelmApp(appPath)
|
||||
targetObjs, err = h.Template(q.AppLabel, q.ValueFiles, q.ComponentParameterOverrides)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
params, err = h.GetParameters(q.ValueFiles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case AppSourceDirectory:
|
||||
targetObjs, err = findManifests(appPath)
|
||||
}
|
||||
@@ -237,12 +244,23 @@ func tempRepoPath(repo string) string {
|
||||
return path.Join(os.TempDir(), strings.Replace(repo, "/", "_", -1))
|
||||
}
|
||||
|
||||
// identifyAppSourceType examines a directory and determines its application source type
|
||||
func identifyAppSourceType(appPath string) AppSourceType {
|
||||
if pathExists(path.Join(appPath, "app.yaml")) {
|
||||
// IdentifyAppSourceTypeByAppDir examines a directory and determines its application source type
|
||||
func IdentifyAppSourceTypeByAppDir(appDirPath string) AppSourceType {
|
||||
if pathExists(path.Join(appDirPath, "app.yaml")) {
|
||||
return AppSourceKsonnet
|
||||
}
|
||||
if pathExists(path.Join(appPath, "Chart.yaml")) {
|
||||
if pathExists(path.Join(appDirPath, "Chart.yaml")) {
|
||||
return AppSourceHelm
|
||||
}
|
||||
return AppSourceDirectory
|
||||
}
|
||||
|
||||
// IdentifyAppSourceTypeByAppPath determines application source type by app file path
|
||||
func IdentifyAppSourceTypeByAppPath(appFilePath string) AppSourceType {
|
||||
if strings.HasSuffix(appFilePath, "app.yaml") {
|
||||
return AppSourceKsonnet
|
||||
}
|
||||
if strings.HasSuffix(appFilePath, "Chart.yaml") {
|
||||
return AppSourceHelm
|
||||
}
|
||||
return AppSourceDirectory
|
||||
|
||||
@@ -214,23 +214,32 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *ApplicationResourceE
|
||||
if !s.enf.EnforceClaims(ctx.Value("claims"), "applications/events", "get", appRBACName(*a)) {
|
||||
return nil, grpc.ErrPermissionDenied
|
||||
}
|
||||
config, namespace, err := s.getApplicationClusterConfig(*q.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kubeClientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var fieldSelector string
|
||||
var (
|
||||
kubeClientset kubernetes.Interface
|
||||
fieldSelector string
|
||||
namespace string
|
||||
)
|
||||
// There are two places where we get events. If we are getting application events, we query
|
||||
// our own cluster. If it is events on a resource on an external cluster, then we query the
|
||||
// external cluster using its rest.Config
|
||||
if q.ResourceName == "" && q.ResourceUID == "" {
|
||||
kubeClientset = s.kubeclientset
|
||||
namespace = a.Namespace
|
||||
fieldSelector = fields.SelectorFromSet(map[string]string{
|
||||
"involvedObject.name": a.Name,
|
||||
"involvedObject.uid": string(a.UID),
|
||||
"involvedObject.namespace": namespace,
|
||||
"involvedObject.namespace": a.Namespace,
|
||||
}).String()
|
||||
} else {
|
||||
var config *rest.Config
|
||||
config, namespace, err = s.getApplicationClusterConfig(*q.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kubeClientset, err = kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldSelector = fields.SelectorFromSet(map[string]string{
|
||||
"involvedObject.name": q.ResourceName,
|
||||
"involvedObject.uid": q.ResourceUID,
|
||||
@@ -240,7 +249,6 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *ApplicationResourceE
|
||||
|
||||
log.Infof("Querying for resource events with field selector: %s", fieldSelector)
|
||||
opts := metav1.ListOptions{FieldSelector: fieldSelector}
|
||||
|
||||
return kubeClientset.CoreV1().Events(namespace).List(opts)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"path"
|
||||
"reflect"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@@ -75,84 +76,96 @@ func (s *Server) ListApps(ctx context.Context, q *RepoAppsQuery) (*RepoAppsRespo
|
||||
revision = "HEAD"
|
||||
}
|
||||
|
||||
ksonnetApps, err := s.listKsonnetApps(ctx, repo, revision, repoClient)
|
||||
ksonnetRes, err := repoClient.ListDir(ctx, &repository.ListDirRequest{Repo: repo, Revision: revision, Path: "*app.yaml"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
helmApps, err := s.listHelmApps(ctx, repo, revision, repoClient)
|
||||
helmRes, err := repoClient.ListDir(ctx, &repository.ListDirRequest{Repo: repo, Revision: revision, Path: "*Chart.yaml"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &RepoAppsResponse{
|
||||
KsonnetApps: ksonnetApps,
|
||||
HelmApps: helmApps,
|
||||
}, nil
|
||||
items := make([]*AppInfo, 0)
|
||||
|
||||
for i := range ksonnetRes.Items {
|
||||
items = append(items, &AppInfo{Type: string(repository.AppSourceKsonnet), Path: ksonnetRes.Items[i]})
|
||||
}
|
||||
|
||||
for i := range helmRes.Items {
|
||||
items = append(items, &AppInfo{Type: string(repository.AppSourceHelm), Path: helmRes.Items[i]})
|
||||
}
|
||||
|
||||
return &RepoAppsResponse{Items: items}, nil
|
||||
}
|
||||
|
||||
func (s *Server) listHelmApps(ctx context.Context, repo *appsv1.Repository, revision string, repoClient repository.RepositoryServiceClient) ([]*HelmAppSpec, error) {
|
||||
req := repository.ListDirRequest{
|
||||
Repo: repo,
|
||||
Revision: revision,
|
||||
Path: "*Chart.yaml",
|
||||
func (s *Server) GetAppDetails(ctx context.Context, q *RepoAppDetailsQuery) (*RepoAppDetailsResponse, error) {
|
||||
if !s.enf.EnforceClaims(ctx.Value("claims"), "repositories/apps", "get", q.Repo) {
|
||||
return nil, grpc.ErrPermissionDenied
|
||||
}
|
||||
getRes, err := repoClient.ListDir(ctx, &req)
|
||||
repo, err := s.db.GetRepository(ctx, q.Repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
helmApps := make([]*HelmAppSpec, 0)
|
||||
for _, path := range getRes.Items {
|
||||
getFileRes, err := repoClient.GetFile(ctx, &repository.GetFileRequest{
|
||||
Repo: repo,
|
||||
Revision: revision,
|
||||
Path: path,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var appSpec HelmAppSpec
|
||||
appSpec.Path = path
|
||||
err = yaml.Unmarshal(getFileRes.Data, &appSpec)
|
||||
if err == nil && appSpec.Name != "" {
|
||||
helmApps = append(helmApps, &appSpec)
|
||||
}
|
||||
// Test the repo
|
||||
conn, repoClient, err := s.repoClientset.NewRepositoryClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return helmApps, nil
|
||||
}
|
||||
defer util.Close(conn)
|
||||
|
||||
func (s *Server) listKsonnetApps(ctx context.Context, repo *appsv1.Repository, revision string, repoClient repository.RepositoryServiceClient) ([]*KsonnetAppSpec, error) {
|
||||
req := repository.ListDirRequest{
|
||||
revision := q.Revision
|
||||
if revision == "" {
|
||||
revision = "HEAD"
|
||||
}
|
||||
|
||||
appSpecRes, err := repoClient.GetFile(ctx, &repository.GetFileRequest{
|
||||
Repo: repo,
|
||||
Revision: revision,
|
||||
Path: "*app.yaml",
|
||||
}
|
||||
getRes, err := repoClient.ListDir(ctx, &req)
|
||||
Path: q.Path,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ksonnetApps := make([]*KsonnetAppSpec, 0)
|
||||
for _, path := range getRes.Items {
|
||||
getFileRes, err := repoClient.GetFile(ctx, &repository.GetFileRequest{
|
||||
Repo: repo,
|
||||
Revision: revision,
|
||||
Path: path,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
appSourceType := repository.IdentifyAppSourceTypeByAppPath(q.Path)
|
||||
switch appSourceType {
|
||||
case repository.AppSourceKsonnet:
|
||||
var appSpec KsonnetAppSpec
|
||||
appSpec.Path = path
|
||||
err = yaml.Unmarshal(getFileRes.Data, &appSpec)
|
||||
if err == nil && appSpec.Name != "" && len(appSpec.Environments) > 0 {
|
||||
ksonnetApps = append(ksonnetApps, &appSpec)
|
||||
appSpec.Path = q.Path
|
||||
err = yaml.Unmarshal(appSpecRes.Data, &appSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RepoAppDetailsResponse{
|
||||
Type: string(appSourceType),
|
||||
Ksonnet: &appSpec,
|
||||
}, nil
|
||||
case repository.AppSourceHelm:
|
||||
var appSpec HelmAppSpec
|
||||
appSpec.Path = q.Path
|
||||
err = yaml.Unmarshal(appSpecRes.Data, &appSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valuesFilesRes, err := repoClient.ListDir(ctx, &repository.ListDirRequest{
|
||||
Revision: revision,
|
||||
Repo: repo,
|
||||
Path: path.Join(path.Dir(q.Path), "*values*.yaml"),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
appSpec.ValueFiles = valuesFilesRes.Items
|
||||
return &RepoAppDetailsResponse{
|
||||
Type: string(appSourceType),
|
||||
Helm: &appSpec,
|
||||
}, nil
|
||||
|
||||
}
|
||||
return ksonnetApps, nil
|
||||
|
||||
return nil, status.Errorf(codes.InvalidArgument, "specified application path is not supported")
|
||||
}
|
||||
|
||||
// Create creates a repository
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -80,6 +80,52 @@ func request_RepositoryService_ListApps_0(ctx context.Context, marshaler runtime
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_RepositoryService_GetAppDetails_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0, "path": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
|
||||
)
|
||||
|
||||
func request_RepositoryService_GetAppDetails_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq RepoAppDetailsQuery
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["repo"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "repo")
|
||||
}
|
||||
|
||||
protoReq.Repo, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "repo", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["path"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "path")
|
||||
}
|
||||
|
||||
protoReq.Path, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "path", err)
|
||||
}
|
||||
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_RepositoryService_GetAppDetails_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetAppDetails(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_RepositoryService_Create_0 = &utilities.DoubleArray{Encoding: map[string]int{"repo": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
@@ -282,6 +328,35 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_RepositoryService_GetAppDetails_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
if cn, ok := w.(http.CloseNotifier); ok {
|
||||
go func(done <-chan struct{}, closed <-chan bool) {
|
||||
select {
|
||||
case <-done:
|
||||
case <-closed:
|
||||
cancel()
|
||||
}
|
||||
}(ctx.Done(), cn.CloseNotify())
|
||||
}
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_RepositoryService_GetAppDetails_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_RepositoryService_GetAppDetails_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_RepositoryService_Create_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -406,6 +481,8 @@ var (
|
||||
|
||||
pattern_RepositoryService_ListApps_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "repositories", "repo", "apps"}, ""))
|
||||
|
||||
pattern_RepositoryService_GetAppDetails_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "repositories", "repo", "apps", "path"}, ""))
|
||||
|
||||
pattern_RepositoryService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repositories"}, ""))
|
||||
|
||||
pattern_RepositoryService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo"}, ""))
|
||||
@@ -420,6 +497,8 @@ var (
|
||||
|
||||
forward_RepositoryService_ListApps_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RepositoryService_GetAppDetails_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RepositoryService_Create_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_RepositoryService_Get_0 = runtime.ForwardResponseMessage
|
||||
|
||||
@@ -17,10 +17,30 @@ message RepoAppsQuery {
|
||||
string revision = 2;
|
||||
}
|
||||
|
||||
|
||||
// AppInfo contains application type and app file path
|
||||
message AppInfo {
|
||||
string type = 1;
|
||||
string path = 2;
|
||||
}
|
||||
|
||||
// RepoAppDetailsQuery contains query information for app details request
|
||||
message RepoAppDetailsQuery {
|
||||
string repo = 1;
|
||||
string revision = 2;
|
||||
string path = 3;
|
||||
}
|
||||
|
||||
// RepoAppDetailsResponse application details
|
||||
message RepoAppDetailsResponse {
|
||||
string type = 1;
|
||||
KsonnetAppSpec ksonnet = 2;
|
||||
HelmAppSpec helm = 3;
|
||||
}
|
||||
|
||||
// RepoAppsResponse contains applications of specified repository
|
||||
message RepoAppsResponse {
|
||||
repeated KsonnetAppSpec ksonnetApps = 1;
|
||||
repeated HelmAppSpec helmApps = 2;
|
||||
repeated AppInfo items = 1;
|
||||
}
|
||||
|
||||
// KsonnetAppSpec contains Ksonnet app response
|
||||
@@ -35,6 +55,7 @@ message KsonnetAppSpec {
|
||||
message HelmAppSpec {
|
||||
string name = 1;
|
||||
string path = 2;
|
||||
repeated string valueFiles = 3;
|
||||
}
|
||||
|
||||
message KsonnetEnvironment {
|
||||
@@ -79,11 +100,16 @@ service RepositoryService {
|
||||
option (google.api.http).get = "/api/v1/repositories";
|
||||
}
|
||||
|
||||
// ListKsonnetApps returns list of Ksonnet apps in the repo
|
||||
// ListApps returns list of apps in the repo
|
||||
rpc ListApps(RepoAppsQuery) returns (RepoAppsResponse) {
|
||||
option (google.api.http).get = "/api/v1/repositories/{repo}/apps";
|
||||
}
|
||||
|
||||
// GetAppDetails returns application details by given path
|
||||
rpc GetAppDetails(RepoAppDetailsQuery) returns (RepoAppDetailsResponse) {
|
||||
option (google.api.http).get = "/api/v1/repositories/{repo}/apps/{path}";
|
||||
}
|
||||
|
||||
// Create creates a repo
|
||||
rpc Create(RepoCreateRequest) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository) {
|
||||
option (google.api.http) = {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -520,22 +521,17 @@ type bug21955Workaround struct {
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
var pathPatters = []*regexp.Regexp{
|
||||
regexp.MustCompile(`/api/v1/clusters/[^/]+`),
|
||||
regexp.MustCompile(`/api/v1/repositories/[^/]+`),
|
||||
regexp.MustCompile(`/api/v1/repositories/[^/]+/apps`),
|
||||
regexp.MustCompile(`/api/v1/repositories/[^/]+/apps/[^/]+`),
|
||||
}
|
||||
|
||||
func (bf *bug21955Workaround) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
paths := map[string][]string{
|
||||
"/api/v1/repositories/": {"apps"},
|
||||
"/api/v1/clusters/": {},
|
||||
}
|
||||
for path, subPaths := range paths {
|
||||
if strings.Index(r.URL.Path, path) > -1 {
|
||||
postfix := ""
|
||||
for _, subPath := range subPaths {
|
||||
if strings.LastIndex(r.URL.Path, subPath) == len(r.URL.Path)-len(subPath) {
|
||||
postfix = "/" + subPath
|
||||
r.URL.Path = r.URL.Path[0 : len(r.URL.Path)-len(subPath)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
r.URL.Path = path + url.QueryEscape(r.URL.Path[len(path):]) + postfix
|
||||
for _, pattern := range pathPatters {
|
||||
if pattern.MatchString(r.URL.RawPath) {
|
||||
r.URL.Path = r.URL.RawPath
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -555,6 +551,17 @@ func bug21955WorkaroundInterceptor(ctx context.Context, req interface{}, _ *grpc
|
||||
return nil, err
|
||||
}
|
||||
rk.Repo = repo
|
||||
} else if rdq, ok := req.(*repository.RepoAppDetailsQuery); ok {
|
||||
repo, err := url.QueryUnescape(rdq.Repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path, err := url.QueryUnescape(rdq.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rdq.Repo = repo
|
||||
rdq.Path = path
|
||||
} else if ru, ok := req.(*repository.RepoUpdateRequest); ok {
|
||||
repo, err := url.QueryUnescape(ru.Repo.Repo)
|
||||
if err != nil {
|
||||
|
||||
@@ -884,7 +884,7 @@
|
||||
"tags": [
|
||||
"RepositoryService"
|
||||
],
|
||||
"summary": "ListKsonnetApps returns list of Ksonnet apps in the repo",
|
||||
"summary": "ListApps returns list of apps in the repo",
|
||||
"operationId": "ListApps",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -909,6 +909,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/repositories/{repo}/apps/{path}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"RepositoryService"
|
||||
],
|
||||
"summary": "GetAppDetails returns application details by given path",
|
||||
"operationId": "GetAppDetails",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "path",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "revision",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "(empty)",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/repositoryRepoAppDetailsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/session": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -1236,6 +1272,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"repositoryAppInfo": {
|
||||
"type": "object",
|
||||
"title": "AppInfo contains application type and app file path",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repositoryHelmAppSpec": {
|
||||
"type": "object",
|
||||
"title": "HelmAppSpec contains helm app name and path in source repo",
|
||||
@@ -1245,6 +1293,12 @@
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"valueFiles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1325,20 +1379,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"repositoryRepoAppDetailsResponse": {
|
||||
"type": "object",
|
||||
"title": "RepoAppDetailsResponse application details",
|
||||
"properties": {
|
||||
"helm": {
|
||||
"$ref": "#/definitions/repositoryHelmAppSpec"
|
||||
},
|
||||
"ksonnet": {
|
||||
"$ref": "#/definitions/repositoryKsonnetAppSpec"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repositoryRepoAppsResponse": {
|
||||
"type": "object",
|
||||
"title": "RepoAppsResponse contains applications of specified repository",
|
||||
"properties": {
|
||||
"helmApps": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repositoryHelmAppSpec"
|
||||
}
|
||||
},
|
||||
"ksonnetApps": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repositoryKsonnetAppSpec"
|
||||
"$ref": "#/definitions/repositoryAppInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1742,7 +1805,7 @@
|
||||
"$ref": "#/definitions/v1alpha1ApplicationDestination"
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"sourceRepos": {
|
||||
"type": "array",
|
||||
"title": "SourceRepos contains list of git repository URLs which can be used for deployment",
|
||||
"items": {
|
||||
|
||||
@@ -170,7 +170,7 @@ func TestAppManagement(t *testing.T) {
|
||||
|
||||
WaitUntil(t, func() (done bool, err error) {
|
||||
app, err := fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{})
|
||||
return err == nil && app.Status.ComparisonResult.Status != v1alpha1.ComparisonStatusUnknown && len(app.Status.Conditions) > 0, err
|
||||
return err == nil && app.Status.ComparisonResult.Status == v1alpha1.ComparisonStatusUnknown && len(app.Status.Conditions) > 0, err
|
||||
})
|
||||
|
||||
app, err := fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{})
|
||||
|
||||
@@ -17,7 +17,8 @@ func TestMain(m *testing.M) {
|
||||
println(fmt.Sprintf("Unable to create e2e fixture: %v", err))
|
||||
os.Exit(-1)
|
||||
} else {
|
||||
defer fixture.TearDown()
|
||||
m.Run()
|
||||
code := m.Run()
|
||||
fixture.TearDown()
|
||||
os.Exit(code)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,11 +308,13 @@ func queryAppSourceType(ctx context.Context, spec *argoappv1.ApplicationSpec, re
|
||||
return "", err
|
||||
}
|
||||
for _, gitPath := range getRes.Items {
|
||||
// gitPath may look like: app.yaml, or some/subpath/app.yaml
|
||||
trimmedPath := strings.TrimPrefix(gitPath, spec.Source.Path)
|
||||
if trimmedPath == "/app.yaml" {
|
||||
trimmedPath = strings.TrimPrefix(trimmedPath, "/")
|
||||
if trimmedPath == "app.yaml" {
|
||||
return repository.AppSourceKsonnet, nil
|
||||
}
|
||||
if trimmedPath == "/Chart.yaml" {
|
||||
if trimmedPath == "Chart.yaml" {
|
||||
return repository.AppSourceHelm, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ package helm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
@@ -16,7 +18,9 @@ import (
|
||||
// Helm provides wrapper functionality around the `helm` command.
|
||||
type Helm interface {
|
||||
// Template returns a list of unstructured objects from a `helm template` command
|
||||
Template(name string, valuesFiles []string, params []*argoappv1.ComponentParameter) ([]*unstructured.Unstructured, error)
|
||||
Template(name string, valuesFiles []string, overrides []*argoappv1.ComponentParameter) ([]*unstructured.Unstructured, error)
|
||||
// GetParameters returns a list of chart parameters taking into account values in provided YAML files.
|
||||
GetParameters(valuesFiles []string) ([]*argoappv1.ComponentParameter, error)
|
||||
}
|
||||
|
||||
// NewHelmApp create a new wrapper to run commands on the `helm` command-line tool.
|
||||
@@ -28,16 +32,57 @@ type helm struct {
|
||||
path string
|
||||
}
|
||||
|
||||
func (h *helm) Template(name string, valuesFiles []string, params []*argoappv1.ComponentParameter) ([]*unstructured.Unstructured, error) {
|
||||
func (h *helm) Template(name string, valuesFiles []string, overrides []*argoappv1.ComponentParameter) ([]*unstructured.Unstructured, error) {
|
||||
args := []string{
|
||||
"template", h.path, "--name", name,
|
||||
}
|
||||
for _, valuesFile := range valuesFiles {
|
||||
args = append(args, "-f", path.Join(h.path, valuesFile))
|
||||
}
|
||||
for _, p := range params {
|
||||
for _, p := range overrides {
|
||||
args = append(args, "--set", fmt.Sprintf("%s=%s", p.Name, p.Value))
|
||||
}
|
||||
out, err := helmCmd(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kube.SplitYAML(out)
|
||||
}
|
||||
|
||||
func (h *helm) GetParameters(valuesFiles []string) ([]*argoappv1.ComponentParameter, error) {
|
||||
out, err := helmCmd("inspect", "values", h.path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := append([]string{out})
|
||||
for _, file := range valuesFiles {
|
||||
fileValues, err := ioutil.ReadFile(path.Join(h.path, file))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read value file %s: %s", file, err)
|
||||
}
|
||||
values = append(values, string(fileValues))
|
||||
}
|
||||
|
||||
output := map[string]string{}
|
||||
for _, file := range values {
|
||||
values := map[string]interface{}{}
|
||||
if err = yaml.Unmarshal([]byte(file), &values); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse values: %s", err)
|
||||
}
|
||||
flatVals(values, output)
|
||||
}
|
||||
|
||||
params := make([]*argoappv1.ComponentParameter, 0)
|
||||
for key, val := range output {
|
||||
params = append(params, &argoappv1.ComponentParameter{
|
||||
Name: key,
|
||||
Value: val,
|
||||
})
|
||||
}
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func helmCmd(args ...string) (string, error) {
|
||||
cmd := exec.Command("helm", args...)
|
||||
cmdStr := strings.Join(cmd.Args, " ")
|
||||
log.Info(cmdStr)
|
||||
@@ -45,13 +90,23 @@ func (h *helm) Template(name string, valuesFiles []string, params []*argoappv1.C
|
||||
if err != nil {
|
||||
exErr, ok := err.(*exec.ExitError)
|
||||
if !ok {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
errOutput := string(exErr.Stderr)
|
||||
log.Errorf("`%s` failed: %s", cmdStr, errOutput)
|
||||
return nil, fmt.Errorf(strings.TrimSpace(errOutput))
|
||||
return "", fmt.Errorf(strings.TrimSpace(errOutput))
|
||||
}
|
||||
out := string(outBytes)
|
||||
log.Debug(out)
|
||||
return kube.SplitYAML(out)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func flatVals(input map[string]interface{}, output map[string]string, prefixes ...string) {
|
||||
for key, val := range input {
|
||||
if subMap, ok := val.(map[string]interface{}); ok {
|
||||
flatVals(subMap, output, append(prefixes, fmt.Sprintf("%v", key))...)
|
||||
} else {
|
||||
output[strings.Join(append(prefixes, fmt.Sprintf("%v", key)), ".")] = fmt.Sprintf("%v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,18 @@ import (
|
||||
argoappv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
|
||||
func findParameter(params []*argoappv1.ComponentParameter, name string) *argoappv1.ComponentParameter {
|
||||
for _, param := range params {
|
||||
if param.Name == name {
|
||||
return param
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestHelmTemplateParams(t *testing.T) {
|
||||
h := NewHelmApp("./testdata/minio")
|
||||
params := []*argoappv1.ComponentParameter{
|
||||
overrides := []*argoappv1.ComponentParameter{
|
||||
{
|
||||
Name: "service.type",
|
||||
Value: "LoadBalancer",
|
||||
@@ -23,7 +32,7 @@ func TestHelmTemplateParams(t *testing.T) {
|
||||
Value: "1234",
|
||||
},
|
||||
}
|
||||
objs, err := h.Template("test", nil, params)
|
||||
objs, err := h.Template("test", nil, overrides)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, len(objs))
|
||||
|
||||
@@ -51,7 +60,27 @@ func TestHelmTemplateValues(t *testing.T) {
|
||||
err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int32(3), *dep.Spec.Replicas)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestHelmGetParams(t *testing.T) {
|
||||
h := NewHelmApp("./testdata/redis")
|
||||
params, err := h.GetParameters([]string{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
slaveCountParam := findParameter(params, "cluster.slaveCount")
|
||||
assert.NotNil(t, slaveCountParam)
|
||||
assert.Equal(t, slaveCountParam.Value, "1")
|
||||
}
|
||||
|
||||
func TestHelmGetParamsValueFiles(t *testing.T) {
|
||||
h := NewHelmApp("./testdata/redis")
|
||||
params, err := h.GetParameters([]string{"values-production.yaml"})
|
||||
assert.Nil(t, err)
|
||||
|
||||
slaveCountParam := findParameter(params, "cluster.slaveCount")
|
||||
assert.NotNil(t, slaveCountParam)
|
||||
assert.Equal(t, slaveCountParam.Value, "3")
|
||||
}
|
||||
|
||||
@@ -174,7 +174,11 @@ func GetCachedServerResources(host string, disco discovery.DiscoveryInterface) (
|
||||
}
|
||||
resList, err = disco.ServerResources()
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
if len(resList) == 0 {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
// It's possible for ServerResources to return error as well as a resource list
|
||||
log.Warnf("Resource discovery partially successful. Encountered error: %v", err)
|
||||
}
|
||||
err = apiResourceCache.Set(&cache.Item{
|
||||
Key: cacheKey,
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/argoproj/argo-cd/common"
|
||||
jwtutil "github.com/argoproj/argo-cd/util/jwt"
|
||||
passwordutil "github.com/argoproj/argo-cd/util/password"
|
||||
"github.com/argoproj/argo-cd/util/settings"
|
||||
)
|
||||
@@ -166,26 +167,21 @@ func (mgr *SessionManager) VerifyToken(tokenString string) (jwt.Claims, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func stringFromMap(input map[string]interface{}, key string) string {
|
||||
if val, ok := input[key]; ok {
|
||||
if res, ok := val.(string); ok {
|
||||
return res
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func Username(ctx context.Context) string {
|
||||
if claims, ok := ctx.Value("claims").(*jwt.MapClaims); ok {
|
||||
mapClaims := *claims
|
||||
switch stringFromMap(mapClaims, "iss") {
|
||||
case SessionManagerClaimsIssuer:
|
||||
return stringFromMap(mapClaims, "sub")
|
||||
default:
|
||||
return stringFromMap(mapClaims, "email")
|
||||
}
|
||||
claims, ok := ctx.Value("claims").(jwt.Claims)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
mapClaims, err := jwtutil.MapClaims(claims)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
switch jwtutil.GetField(mapClaims, "iss") {
|
||||
case SessionManagerClaimsIssuer:
|
||||
return jwtutil.GetField(mapClaims, "sub")
|
||||
default:
|
||||
return jwtutil.GetField(mapClaims, "email")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// MakeCookieMetadata generates a string representing a Web cookie. Yum!
|
||||
|
||||
Reference in New Issue
Block a user