diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html
index 01c16c5e21..97501ccc56 100644
--- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html
+++ b/src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/tabs/build-tab/build-tab.component.html
@@ -189,4 +189,32 @@
-
\ No newline at end of file
+
+
+
+
+
+
+ Additional Application Info
+
+
+ {{ appSvc.app.entity.guid }}
+ {{ appSvc.app.entity.command || appSvc.app.entity.detected_start_command || '-' }}
+ {{ appSvc.app.entity.ports || '-' }}
+
+
+
+
+
+
+ Health Check Configuration
+
+
+ {{ appSvc.app.entity.health_check_type }}
+ {{ appSvc.app.entity.health_check_timeout | uptime }}
+ {{ appSvc.app.entity.health_check_http_endpoint }}
+
+
+
+
+
diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-deployer.ts b/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-deployer.ts
index e30e566377..cf15a1c671 100644
--- a/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-deployer.ts
+++ b/src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-deployer.ts
@@ -1,5 +1,5 @@
import { Store } from '@ngrx/store';
-import { BehaviorSubject, Observable, of as observableOf, Subject, Subscription } from 'rxjs';
+import { BehaviorSubject, of as observableOf, Subject, Subscription } from 'rxjs';
import websocketConnect from 'rxjs-websockets';
import { catchError, combineLatest, filter, first, map, mergeMap, share, switchMap, tap } from 'rxjs/operators';
@@ -91,7 +91,7 @@ export class DeployApplicationDeployer {
// Status of file transfers
fileTransferStatus$ = new BehaviorSubject(undefined);
- public messages: Observable;
+ public messages = new BehaviorSubject('');
// Are we deploying?
deploying = false;
@@ -165,13 +165,14 @@ export class DeployApplicationDeployer {
this.applicationSource = appDetail.applicationSource;
this.applicationOverrides = appDetail.applicationOverrides;
const host = window.location.host;
+ const appId = this.isRedeploy ? `&app=${this.isRedeploy}` : '';
const streamUrl = (
`wss://${host}/pp/${this.proxyAPIVersion}/${this.cfGuid}/${this.orgGuid}/${this.spaceGuid}/deploy` +
- `?org=${org.entity.name}&space=${space.entity.name}`
+ `?org=${org.entity.name}&space=${space.entity.name}${appId}`
);
this.inputStream = new Subject();
- this.messages = websocketConnect(streamUrl)
+ const buffer = websocketConnect(streamUrl)
.pipe(
switchMap((get) => get(this.inputStream)),
catchError(e => {
@@ -189,7 +190,16 @@ export class DeployApplicationDeployer {
map((log) => log.message),
share(),
);
- this.msgSub = this.messages.subscribe();
+
+ // Buffer messages until each newline character
+ let b = '';
+ this.msgSub = buffer.subscribe(m => {
+ b = b + m;
+ if (b.endsWith('\n')) {
+ this.messages.next(b);
+ b = '';
+ }
+ });
})
).subscribe();
diff --git a/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-list-config-deploy.service.ts b/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-list-config-deploy.service.ts
index 8dcb0bf35b..85fe999819 100644
--- a/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-list-config-deploy.service.ts
+++ b/src/frontend/packages/core/src/shared/components/list/list-types/github-commits/github-commits-list-config-deploy.service.ts
@@ -44,13 +44,15 @@ export class GithubCommitsListConfigServiceDeploy extends GithubCommitsListConfi
this.initialised.next(true);
// Auto-select first commit - wait for page to load, select first item if present
- this.dataSource.page$.pipe(
- first()
- ).subscribe(rs => {
- if (rs && rs.length > 0) {
- this.dataSource.selectedRowToggle(rs[0], false);
- }
- });
+ setTimeout(() => {
+ this.dataSource.page$.pipe(
+ first()
+ ).subscribe(rs => {
+ if (rs && rs.length > 0) {
+ this.dataSource.selectedRowToggle(rs[0], false);
+ }
+ });
+ }, 0);
});
}
}
diff --git a/src/jetstream/go.mod b/src/jetstream/go.mod
index da7f830108..aecae07f82 100644
--- a/src/jetstream/go.mod
+++ b/src/jetstream/go.mod
@@ -5,14 +5,21 @@ go 1.12
require (
bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c
code.cloudfoundry.org/bytefmt v0.0.0-20180906201452-2aa6f33b730c // indirect
- code.cloudfoundry.org/cli v6.43.0+incompatible
+ code.cloudfoundry.org/cfnetworking-cli-api v0.0.0-20190103195135-4b04f26287a6 // indirect
+ code.cloudfoundry.org/cli v6.49.0+incompatible
+ code.cloudfoundry.org/diego-ssh v0.0.0-20200312183824-517d22c5d890 // indirect
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect
+ code.cloudfoundry.org/inigo v0.0.0-20200318144131-597cd5dbfe8b // indirect
+ code.cloudfoundry.org/lager v2.0.0+incompatible // indirect
+ code.cloudfoundry.org/ykk v0.0.0-20170424192843-e4df4ce2fd4d // indirect
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
- github.com/SermoDigital/jose v0.9.1
+ github.com/SermoDigital/jose v0.9.1 // indirect
github.com/Sirupsen/logrus v0.0.0-00010101000000-000000000000 // indirect
github.com/antonlindstrom/pgstore v0.0.0-20170604072116-a407030ba6d0
+ github.com/apoydence/eachers v0.0.0-20181020210610-23942921fe77 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/bmatcuk/doublestar v1.1.1 // indirect
+ github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 // indirect
github.com/cf-stratos/mysqlstore v0.0.0-20170822100912-304308519d13
github.com/charlievieth/fs v0.0.0-20170613215519-7dc373669fa1 // indirect
github.com/cloudfoundry-community/go-cfenv v1.17.0
@@ -24,13 +31,18 @@ require (
github.com/cppforlife/go-patch v0.2.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
+ github.com/docker/distribution v2.7.1+incompatible // indirect
+ github.com/docker/docker v1.13.1 // indirect
github.com/domodwyer/mailyak v3.1.1+incompatible
github.com/dsnet/compress v0.0.0-20171208185109-cc9eb1d7ad76 // indirect
+ github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad // indirect
+ github.com/elazarl/goproxy/ext v0.0.0-20200315184450-1f3cb6622dad // indirect
github.com/fatih/color v1.7.0 // indirect
github.com/go-sql-driver/mysql v1.4.1
github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect
+ github.com/google/martian v2.1.0+incompatible // indirect
github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e // indirect
github.com/gorilla/context v1.1.1
github.com/gorilla/securecookie v1.1.1
@@ -40,7 +52,8 @@ require (
github.com/jessevdk/go-flags v1.4.0 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12
- github.com/kubeapps/common v0.0.0-20181107174310-61d8eb6f11b4
+ github.com/kr/pty v1.1.8 // indirect
+ github.com/kubeapps/common v0.0.0-20181107174310-61d8eb6f11b4 // indirect
github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28 // indirect
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0 // indirect
@@ -59,12 +72,18 @@ require (
github.com/nwmac/sqlitestore v0.0.0-20180824125213-7d2ab221fb3f
github.com/onsi/ginkgo v1.11.0 // indirect
github.com/onsi/gomega v1.8.1 // indirect
+ github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
github.com/pkg/errors v0.8.1 // indirect
+ github.com/poy/eachers v0.0.0-20181020210610-23942921fe77 // indirect
+ github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 // indirect
+ github.com/sajari/fuzzy v1.0.0 // indirect
github.com/satori/go.uuid v1.2.0
github.com/sirupsen/logrus v1.3.0
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3 // indirect
github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa
+ github.com/tedsuo/ifrit v0.0.0-20191009134036-9a97d0632f00 // indirect
+ github.com/tedsuo/rata v1.0.0 // indirect
github.com/ulikunitz/xz v0.5.6 // indirect
github.com/valyala/fasttemplate v1.1.0 // indirect
github.com/vito/go-interact v0.0.0-20171111012221-fa338ed9e9ec // indirect
diff --git a/src/jetstream/go.sum b/src/jetstream/go.sum
index 85168fd7fd..494c818e50 100644
--- a/src/jetstream/go.sum
+++ b/src/jetstream/go.sum
@@ -4,10 +4,22 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
code.cloudfoundry.org/bytefmt v0.0.0-20180906201452-2aa6f33b730c h1:VzwteSWGbW9mxXTEkH+kpnao5jbgLynw3hq742juQh8=
code.cloudfoundry.org/bytefmt v0.0.0-20180906201452-2aa6f33b730c/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
+code.cloudfoundry.org/cfnetworking-cli-api v0.0.0-20190103195135-4b04f26287a6 h1:Yc9r1p21kEpni9WlG4mwOZw87TB2QlyS9sAEebZ3+ak=
+code.cloudfoundry.org/cfnetworking-cli-api v0.0.0-20190103195135-4b04f26287a6/go.mod h1:u5FovqC5GGAEbFPz+IdjycDA+gIjhUwqxnu0vbHwVeM=
code.cloudfoundry.org/cli v6.43.0+incompatible h1:jAaPyHN5Hb2r2sR9i8Y8ejKPiPpuBYMaHBFyKVmQ7T4=
code.cloudfoundry.org/cli v6.43.0+incompatible/go.mod h1:e4d+EpbwevNhyTZKybrLlyTvpH+W22vMsmdmcTxs/Fo=
+code.cloudfoundry.org/cli v6.49.0+incompatible h1:lUuYux9EXLe8EBzlvckJLpHKhc8szJfWiEc3SXdM8+o=
+code.cloudfoundry.org/cli v6.49.0+incompatible/go.mod h1:e4d+EpbwevNhyTZKybrLlyTvpH+W22vMsmdmcTxs/Fo=
+code.cloudfoundry.org/diego-ssh v0.0.0-20200312183824-517d22c5d890 h1:sr3sHuZSH6puBqQgatzM3hYRrfOc+D8eVv0ykLYwd6o=
+code.cloudfoundry.org/diego-ssh v0.0.0-20200312183824-517d22c5d890/go.mod h1:L2/glHnSK+wKnsG8oZZqdV2sgYY9NDo/I1aDJGhcWaM=
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk=
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI=
+code.cloudfoundry.org/inigo v0.0.0-20200318144131-597cd5dbfe8b h1:TSoj8216L9LEU1MKAI9GSpOpLesalhitn8R4fEn38P8=
+code.cloudfoundry.org/inigo v0.0.0-20200318144131-597cd5dbfe8b/go.mod h1:1ZB1JCh2FAp+SqX79ve6dc8YREvbsziULEOncAilX4Q=
+code.cloudfoundry.org/lager v2.0.0+incompatible h1:WZwDKDB2PLd/oL+USK4b4aEjUymIej9My2nUQ9oWEwQ=
+code.cloudfoundry.org/lager v2.0.0+incompatible/go.mod h1:O2sS7gKP3HM2iemG+EnwvyNQK7pTSC6Foi4QiMp9sSk=
+code.cloudfoundry.org/ykk v0.0.0-20170424192843-e4df4ce2fd4d h1:M+zXqtXJqcsmpL76aU0tdl1ho23eYa4axYoM4gD62UA=
+code.cloudfoundry.org/ykk v0.0.0-20170424192843-e4df4ce2fd4d/go.mod h1:YUJiVOr5xl0N/RjMxM1tHmgSpBbi5UM+KoVR5AoejO0=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
@@ -32,6 +44,8 @@ github.com/SermoDigital/jose v0.9.2-0.20180104203859-803625baeddc h1:MhBvG7RLaLq
github.com/SermoDigital/jose v0.9.2-0.20180104203859-803625baeddc/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
github.com/antonlindstrom/pgstore v0.0.0-20170604072116-a407030ba6d0 h1:e6PEaXbztY0ViaKotCICNnBQDUeNEJgrQ5UAHWlloh4=
github.com/antonlindstrom/pgstore v0.0.0-20170604072116-a407030ba6d0/go.mod h1:2Ti6VUHVxpC0VSmTZzEvpzysnaGAfGBOoMIz5ykPyyw=
+github.com/apoydence/eachers v0.0.0-20181020210610-23942921fe77 h1:afT88tB6u9JCKQZVAAaa9ICz/uGn5Uw9ekn6P22mYKM=
+github.com/apoydence/eachers v0.0.0-20181020210610-23942921fe77/go.mod h1:bXvGk6IkT1Agy7qzJ+DjIw/SJ1AaB3AvAuMDVV+Vkoo=
github.com/arschles/assert v1.0.0/go.mod h1:m/u69zW43x0h8dTHcv3JJZljINyEYgBuf5fYJP6WikI=
github.com/aws/aws-sdk-go v1.17.5 h1:WW9Hm3KYo48iZHpmBc+b7sgyS0h32zgCvya28SLW4BU=
github.com/aws/aws-sdk-go v1.17.5/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
@@ -41,6 +55,8 @@ github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdn
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
+github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo=
+github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
github.com/cf-stratos/mysqlstore v0.0.0-20170822100912-304308519d13 h1:WwIvjUUodNoZduhdhotbKnrLSFoIn5vD3QgNZv0hjvo=
github.com/cf-stratos/mysqlstore v0.0.0-20170822100912-304308519d13/go.mod h1:GgQT0ToC+7JLnMKdDB5d434WwCLC2dpNR2AgTJj/08o=
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U=
@@ -50,6 +66,7 @@ github.com/charlievieth/fs v0.0.0-20170613215519-7dc373669fa1/go.mod h1:sAoA1zHC
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudfoundry-community/go-cfenv v1.17.0 h1:qfxEfn8qKkaHY3ZEk/Y2noY79HBASvNgmtHK9x4+6GY=
github.com/cloudfoundry-community/go-cfenv v1.17.0/go.mod h1:2UgWvQTRXUuIZ/x3KnW6fk6CgPBhcV4UQb/UGIrUyyI=
+github.com/cloudfoundry-incubator/stratos v2.0.0-beta-001+incompatible h1:UUxNbLjhv2cfymub5yNN1tjjqYkteHBBagb4jcbXEIQ=
github.com/cloudfoundry/bosh-cli v5.4.0+incompatible h1:KpT2PBB7nP1QnK8guXeZ/D2k7FZYAOxcveKgYTDEDBI=
github.com/cloudfoundry/bosh-cli v5.4.0+incompatible/go.mod h1:rzIB+e1sn7wQL/TJ54bl/FemPKRhXby5BIMS3tLuWFM=
github.com/cloudfoundry/bosh-utils v0.0.0-20190206192830-9a0affed2bf1 h1:TxcGamw+BaxXTFwZFORzkWNMCHAWjhThxnI24CLS7iE=
@@ -62,6 +79,8 @@ github.com/cloudfoundry/sonde-go v0.0.0-20171206171820-b33733203bb4 h1:cWfya7mo/
github.com/cloudfoundry/sonde-go v0.0.0-20171206171820-b33733203bb4/go.mod h1:GS0pCHd7onIsewbw8Ue9qa9pZPv2V88cUZDttK6KzgI=
github.com/cppforlife/go-patch v0.2.0 h1:Y14MnCQjDlbw7WXT4k+u6DPAA9XnygN4BfrSpI/19RU=
github.com/cppforlife/go-patch v0.2.0/go.mod h1:67a7aIi94FHDZdoeGSJRRFDp66l9MhaAG1yGxpUoFD8=
+github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -81,12 +100,18 @@ github.com/domodwyer/mailyak v3.1.1+incompatible h1:oPtXn3+56LEFbdqH0bpuPRsqtijW
github.com/domodwyer/mailyak v3.1.1+incompatible/go.mod h1:5NNYkn9hxcdNEOmmMx0yultN5VLorZQ+AWQo9iya+UY=
github.com/dsnet/compress v0.0.0-20171208185109-cc9eb1d7ad76 h1:eX+pdPPlD279OWgdx7f6KqIRSONuK7egk+jDx7OM3Ac=
github.com/dsnet/compress v0.0.0-20171208185109-cc9eb1d7ad76/go.mod h1:KjxHHirfLaw19iGT70HvVjHQsL1vq1SRQB4yOsAfy2s=
+github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad h1:zPs0fNF2Io1Qytf92EI2CDJ9oCXZr+NmjEVexrUEdq4=
+github.com/elazarl/goproxy v0.0.0-20200315184450-1f3cb6622dad/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/elazarl/goproxy/ext v0.0.0-20200315184450-1f3cb6622dad h1:3OG8xVCbdeebrE5IsoWl0TP25DWiHDbLUy+EKif7hDE=
+github.com/elazarl/goproxy/ext v0.0.0-20200315184450-1f3cb6622dad/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/evanphx/json-patch v4.1.0+incompatible h1:K1MDoo4AZ4wU0GIU/fPmtZg7VpzLjCxu+UwBD1FvwOc=
github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -120,6 +145,8 @@ github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASu
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
+github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s=
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
@@ -173,6 +200,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kubeapps/common v0.0.0-20181107174310-61d8eb6f11b4 h1:wdTBUArlqtBYGN2Dd4+zsaFxFH0m4iGCHToW10jPX0k=
github.com/kubeapps/common v0.0.0-20181107174310-61d8eb6f11b4/go.mod h1:TsgmjeDpbftqhwPKInJ3v+l+xbHs4goiB6DFb2WqY9c=
github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28 h1:mkl3tvPHIuPaWsLtmHTybJeoVEW7cbePK73Ir8VtruA=
@@ -247,6 +276,8 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/poy/eachers v0.0.0-20181020210610-23942921fe77 h1:SNdqPRvRsVmYR0gKqFvrUKhFizPJ6yDiGQ++VAJIoDg=
+github.com/poy/eachers v0.0.0-20181020210610-23942921fe77/go.mod h1:x1vqpbcMW9T/KRcQ4b48diSiSVtYgvwQ5xzDByEg4WE=
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
@@ -255,8 +286,13 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jO
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 h1:G04eS0JkAIVZfaJLjla9dNxkJCPiKIGZlw9AfOhzOD0=
+github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ=
+github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
+github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -283,6 +319,10 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A=
+github.com/tedsuo/ifrit v0.0.0-20191009134036-9a97d0632f00 h1:mujcChM89zOHwgZBBNr5WZ77mBXP1yR+gLThGCYZgAg=
+github.com/tedsuo/ifrit v0.0.0-20191009134036-9a97d0632f00/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
+github.com/tedsuo/rata v1.0.0 h1:Sf9aZrYy6ElSTncjnGkyC2yuVvz5YJetBIUKJ4CmeKE=
+github.com/tedsuo/rata v1.0.0/go.mod h1:X47ELzhOoLbfFIY0Cql9P6yo3Cdwf2CMX3FVZxRzJPc=
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/unrolled/render v1.0.0 h1:XYtvhA3UkpB7PqkvhUFYmpKD55OudoIeygcfus4vcd4=
@@ -325,6 +365,7 @@ golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226191147-529b322ea346 h1:zxGQKdHVCsCsJpbd7ijKsVC27CyETheUBql7Br2TGmA=
golang.org/x/oauth2 v0.0.0-20190226191147-529b322ea346/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/src/jetstream/plugins/cfapppush/app-repository.go b/src/jetstream/plugins/cfapppush/app-repository.go
deleted file mode 100644
index f75e5749fe..0000000000
--- a/src/jetstream/plugins/cfapppush/app-repository.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package cfapppush
-
-import (
- "code.cloudfoundry.org/cli/cf/api/applications"
- "code.cloudfoundry.org/cli/cf/models"
-
- "github.com/gorilla/websocket"
-)
-
-// RepositoryIntercept allows us to intercept application creation within the push process
-type RepositoryIntercept struct {
- target applications.Repository
- msgSender DeployAppMessageSender
- clientWebsocket *websocket.Conn
-}
-
-// NewRepositoryIntercept creates a new RepositoryIntercept based on the supplied parameters
-func NewRepositoryIntercept(target applications.Repository, msgSender DeployAppMessageSender, clientWebsocket *websocket.Conn) (repo RepositoryIntercept) {
- repo.target = target
- repo.msgSender = msgSender
- repo.clientWebsocket = clientWebsocket
- return
-}
-
-func (repo RepositoryIntercept) sendAppData(app models.Application) {
- repo.msgSender.SendEvent(repo.clientWebsocket, APP_GUID_NOTIFY, app.GUID)
-}
-
-// Create proxies the Create method from models.Application, notifying the application
-func (repo RepositoryIntercept) Create(params models.AppParams) (models.Application, error) {
- app, err := repo.target.Create(params)
- if err == nil {
- repo.sendAppData(app)
- }
- return app, err
-}
-
-// GetApp proxies the GetApp method from models.Application
-func (repo RepositoryIntercept) GetApp(appGUID string) (app models.Application, apiErr error) {
- return repo.target.GetApp(appGUID)
-}
-
-// Read proxies the Read method from models.Application, notifying the application
-func (repo RepositoryIntercept) Read(name string) (app models.Application, apiErr error) {
- app, err := repo.target.Read(name)
- if err == nil {
- repo.sendAppData(app)
- }
- return app, err
-}
-
-// ReadFromSpace proxies the ReadFromSpace method from models.Application
-func (repo RepositoryIntercept) ReadFromSpace(name string, spaceGUID string) (app models.Application, apiErr error) {
- return repo.target.ReadFromSpace(name, spaceGUID)
-}
-
-// Update proxies the Update method from models.Application
-func (repo RepositoryIntercept) Update(appGUID string, params models.AppParams) (updatedApp models.Application, apiErr error) {
- return repo.target.Update(appGUID, params)
-}
-
-// Delete proxies the Delete method from models.Application
-func (repo RepositoryIntercept) Delete(appGUID string) (apiErr error) {
- return repo.target.Delete(appGUID)
-}
-
-// ReadEnv proxies the ReadEnv method from models.Application
-func (repo RepositoryIntercept) ReadEnv(guid string) (*models.Environment, error) {
- return repo.target.ReadEnv(guid)
-}
-
-// CreateRestageRequest proxies the CreateRestageRequest method from models.Application
-func (repo RepositoryIntercept) CreateRestageRequest(guid string) error {
- return repo.target.CreateRestageRequest(guid)
-}
diff --git a/src/jetstream/plugins/cfapppush/deploy.go b/src/jetstream/plugins/cfapppush/deploy.go
index b27c3b8bc0..0bdc453ddb 100644
--- a/src/jetstream/plugins/cfapppush/deploy.go
+++ b/src/jetstream/plugins/cfapppush/deploy.go
@@ -10,7 +10,6 @@ import (
"strings"
"time"
- "github.com/cloudfoundry-incubator/stratos/src/jetstream/plugins/cfapppush/pushapp"
"github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces"
"github.com/gorilla/websocket"
"github.com/labstack/echo"
@@ -72,11 +71,6 @@ const (
stratosProjectKey = "STRATOS_PROJECT"
)
-// DeployAppMessageSender is the interface for sending a message over a web socket
-type DeployAppMessageSender interface {
- SendEvent(clientWebSocket *websocket.Conn, event MessageType, data string)
-}
-
func (cfAppPush *CFAppPush) deploy(echoContext echo.Context) error {
cnsiGUID := echoContext.Param("cnsiGuid")
@@ -85,6 +79,9 @@ func (cfAppPush *CFAppPush) deploy(echoContext echo.Context) error {
spaceName := echoContext.QueryParam("space")
orgName := echoContext.QueryParam("org")
+ // App ID is this is a redeploy
+ appID := echoContext.QueryParam("app")
+
clientWebSocket, pingTicker, err := interfaces.UpgradeToWebSocket(echoContext)
if err != nil {
log.Errorf("Upgrade to websocket failed due to: %+v", err)
@@ -155,7 +152,7 @@ func (cfAppPush *CFAppPush) deploy(echoContext echo.Context) error {
}
log.Debugf("Overrides: %v+", msgOverrides)
- overrides := pushapp.CFPushAppOverrides{}
+ overrides := CFPushAppOverrides{}
if err = json.Unmarshal([]byte(msgOverrides.Message), &overrides); err != nil {
log.Errorf("Error marshalling json: %v+", err)
return err
@@ -190,18 +187,17 @@ func (cfAppPush *CFAppPush) deploy(echoContext echo.Context) error {
return err
}
+ // Send App ID now if we have it (redeploy)
+ if len(appID) > 0 {
+ cfAppPush.SendEvent(clientWebSocket, APP_GUID_NOTIFY, appID)
+ }
+
dialTimeout := cfAppPush.portalProxy.Env().String("CF_DIAL_TIMEOUT", "")
pushConfig.OutputWriter = socketWriter
pushConfig.DialTimeout = dialTimeout
// Initialise Push Command
- cfAppPush.cfPush = pushapp.Constructor(pushConfig)
-
- // Patch in app repo watcher
- // Wrap an interceptor around the application repository so we can get the app details when created/updated
- deps := cfAppPush.cfPush.GetDeps()
- var repo = deps.RepoLocator.GetApplicationRepository()
- cfAppPush.cfPush.PatchApplicationRepository(NewRepositoryIntercept(repo, cfAppPush, clientWebSocket))
+ cfAppPush.cfPush = Constructor(pushConfig, cfAppPush.portalProxy)
err = cfAppPush.cfPush.Init(appDir, manifestFile, overrides)
if err != nil {
@@ -211,7 +207,8 @@ func (cfAppPush *CFAppPush) deploy(echoContext echo.Context) error {
}
sendEvent(clientWebSocket, EVENT_PUSH_STARTED)
- err = cfAppPush.cfPush.Push()
+
+ err = cfAppPush.cfPush.Run(cfAppPush, clientWebSocket)
if err != nil {
log.Warnf("Failed to execute due to: %+v", err)
sendErrorMessage(clientWebSocket, err, CLOSE_PUSH_ERROR)
@@ -466,7 +463,7 @@ func getMarshalledSocketMessage(data string, messageType MessageType) ([]byte, e
return marshalledJSON, err
}
-func (cfAppPush *CFAppPush) getConfigData(echoContext echo.Context, cnsiGUID string, orgGUID string, spaceGUID string, spaceName string, orgName string, clientWebSocket *websocket.Conn) (*pushapp.CFPushAppConfig, error) {
+func (cfAppPush *CFAppPush) getConfigData(echoContext echo.Context, cnsiGUID string, orgGUID string, spaceGUID string, spaceName string, orgName string, clientWebSocket *websocket.Conn) (*CFPushAppConfig, error) {
cnsiRecord, err := cfAppPush.portalProxy.GetCNSIRecord(cnsiGUID)
if err != nil {
@@ -489,7 +486,7 @@ func (cfAppPush *CFAppPush) getConfigData(echoContext echo.Context, cnsiGUID str
return nil, errors.New("Failed to find token record")
}
- config := &pushapp.CFPushAppConfig{
+ config := &CFPushAppConfig{
AuthorizationEndpoint: cnsiRecord.AuthorizationEndpoint,
CFClient: cnsiRecord.ClientId,
CFClientSecret: cnsiRecord.ClientSecret,
@@ -596,7 +593,7 @@ func fetchManifest(repoPath string, stratosProject StratosProject, clientWebSock
if len(envVarMetaData) > 0 {
for i, app := range manifest.Applications {
if len(app.EnvironmentVariables) == 0 {
- app.EnvironmentVariables = make(map[string]interface{})
+ app.EnvironmentVariables = make(map[string]string)
}
app.EnvironmentVariables[stratosProjectKey] = envVarMetaData
manifest.Applications[i] = app
diff --git a/src/jetstream/plugins/cfapppush/info.go b/src/jetstream/plugins/cfapppush/info.go
new file mode 100644
index 0000000000..c32b34cc2c
--- /dev/null
+++ b/src/jetstream/plugins/cfapppush/info.go
@@ -0,0 +1,38 @@
+package cfapppush
+
+import (
+ "errors"
+
+ "github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces"
+
+ "code.cloudfoundry.org/cli/util/configv3"
+ log "github.com/sirupsen/logrus"
+)
+
+// Get the Cloud Foundry Info
+func (c *CFPushApp) setEndpointInfo(config *configv3.Config) error {
+ log.Debug("CF Push Get CF Info")
+
+ apiEndpoint := c.config.APIEndpointURL
+ skipSSLValidation := c.config.SkipSSLValidation
+
+ cfEndpointSpec, err := c.portalProxy.GetEndpointTypeSpec("cf")
+ if err != nil {
+ return err
+ }
+
+ _, endpointInfo, err := cfEndpointSpec.Info(apiEndpoint, skipSSLValidation)
+ if err != nil {
+ return err
+ }
+
+ if info, ok := endpointInfo.(interfaces.V2Info); ok {
+ // Got the info we need - update the config with it
+ config.SetTargetInformation(apiEndpoint, info.APIVersion, info.AuthorizationEndpoint, info.MinCLIVersion, info.DopplerLoggingEndpoint, info.RoutingEndpoint, skipSSLValidation)
+ config.SetAccessToken("bearer " + c.config.AuthToken)
+ } else {
+ return errors.New("Did not get a CF /v2/info response")
+ }
+
+ return nil
+}
diff --git a/src/jetstream/plugins/cfapppush/main.go b/src/jetstream/plugins/cfapppush/main.go
index 605db754c9..25a3596697 100644
--- a/src/jetstream/plugins/cfapppush/main.go
+++ b/src/jetstream/plugins/cfapppush/main.go
@@ -3,7 +3,6 @@ package cfapppush
import (
"errors"
- "github.com/cloudfoundry-incubator/stratos/src/jetstream/plugins/cfapppush/pushapp"
"github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces"
"github.com/labstack/echo"
)
@@ -11,7 +10,7 @@ import (
// CFAppPush is a plugin to allow applications to be pushed to Cloud Foundry from Stratos
type CFAppPush struct {
portalProxy interfaces.PortalProxy
- cfPush pushapp.CFPush
+ cfPush CFPush
}
// Init creates a new CFAppPush
diff --git a/src/jetstream/plugins/cfapppush/progress_bar.go b/src/jetstream/plugins/cfapppush/progress_bar.go
new file mode 100644
index 0000000000..eeaa687eee
--- /dev/null
+++ b/src/jetstream/plugins/cfapppush/progress_bar.go
@@ -0,0 +1,17 @@
+package cfapppush
+
+import (
+ "io"
+)
+
+// Fake progress bar - don't want to show progress in backend logs
+// We could add support for sending this to the client and having a nicer UI there
+type cfPushProgressBar struct{}
+
+func (t *cfPushProgressBar) Ready() {}
+
+func (t *cfPushProgressBar) Complete() {}
+
+func (t *cfPushProgressBar) NewProgressBarWrapper(reader io.Reader, sizeOfFile int64) io.Reader {
+ return reader
+}
diff --git a/src/jetstream/plugins/cfapppush/push_actor.go b/src/jetstream/plugins/cfapppush/push_actor.go
new file mode 100644
index 0000000000..3953f3c928
--- /dev/null
+++ b/src/jetstream/plugins/cfapppush/push_actor.go
@@ -0,0 +1,112 @@
+package cfapppush
+
+import (
+ "io"
+
+ "code.cloudfoundry.org/cli/actor/pushaction"
+ "code.cloudfoundry.org/cli/actor/v2action"
+ "github.com/gorilla/websocket"
+)
+
+type cfV2Actor struct {
+ wrapped pushaction.V2Actor
+ sent bool
+ msgSender DeployAppMessageSender
+ clientWebsocket *websocket.Conn
+}
+
+func (r cfV2Actor) sendAppID(application v2action.Application) {
+ if !r.sent {
+ r.msgSender.SendEvent(r.clientWebsocket, APP_GUID_NOTIFY, application.GUID)
+ r.sent = true
+ }
+}
+
+func (r cfV2Actor) MapRouteToApplication(routeGUID string, appGUID string) (v2action.Warnings, error) {
+ return r.wrapped.MapRouteToApplication(routeGUID, appGUID)
+}
+
+func (r cfV2Actor) BindServiceByApplicationAndServiceInstance(appGUID string, serviceInstanceGUID string) (v2action.Warnings, error) {
+ return r.wrapped.BindServiceByApplicationAndServiceInstance(appGUID, serviceInstanceGUID)
+}
+
+func (r cfV2Actor) CloudControllerAPIVersion() string {
+ return r.wrapped.CloudControllerAPIVersion()
+}
+
+func (r cfV2Actor) CreateApplication(application v2action.Application) (v2action.Application, v2action.Warnings, error) {
+ app, warnings, err := r.wrapped.CreateApplication(application)
+ if err == nil {
+ r.sendAppID(app)
+ }
+ return app, warnings, err
+}
+
+func (r cfV2Actor) CreateRoute(route v2action.Route, generatePort bool) (v2action.Route, v2action.Warnings, error) {
+ return r.wrapped.CreateRoute(route, generatePort)
+}
+
+func (r cfV2Actor) FindRouteBoundToSpaceWithSettings(route v2action.Route) (v2action.Route, v2action.Warnings, error) {
+ return r.wrapped.FindRouteBoundToSpaceWithSettings(route)
+}
+
+func (r cfV2Actor) GetApplicationByNameAndSpace(name string, spaceGUID string) (v2action.Application, v2action.Warnings, error) {
+ app, warnings, err := r.wrapped.GetApplicationByNameAndSpace(name, spaceGUID)
+ if err == nil {
+ r.sendAppID(app)
+ }
+ return app, warnings, err
+}
+
+func (r cfV2Actor) GetApplicationRoutes(applicationGUID string) (v2action.Routes, v2action.Warnings, error) {
+ return r.wrapped.GetApplicationRoutes(applicationGUID)
+}
+
+func (r cfV2Actor) GetDomainsByNameAndOrganization(domainNames []string, orgGUID string) ([]v2action.Domain, v2action.Warnings, error) {
+ return r.wrapped.GetDomainsByNameAndOrganization(domainNames, orgGUID)
+}
+
+func (r cfV2Actor) GetOrganizationDomains(orgGUID string) ([]v2action.Domain, v2action.Warnings, error) {
+ return r.wrapped.GetOrganizationDomains(orgGUID)
+}
+
+func (r cfV2Actor) GetServiceInstanceByNameAndSpace(name string, spaceGUID string) (v2action.ServiceInstance, v2action.Warnings, error) {
+ return r.wrapped.GetServiceInstanceByNameAndSpace(name, spaceGUID)
+}
+
+func (r cfV2Actor) GetServiceInstancesByApplication(appGUID string) ([]v2action.ServiceInstance, v2action.Warnings, error) {
+ return r.wrapped.GetServiceInstancesByApplication(appGUID)
+}
+
+func (r cfV2Actor) GetStack(guid string) (v2action.Stack, v2action.Warnings, error) {
+ return r.wrapped.GetStack(guid)
+}
+
+func (r cfV2Actor) GetStackByName(stackName string) (v2action.Stack, v2action.Warnings, error) {
+ return r.wrapped.GetStackByName(stackName)
+}
+
+func (r cfV2Actor) PollJob(job v2action.Job) (v2action.Warnings, error) {
+ return r.wrapped.PollJob(job)
+}
+
+func (r cfV2Actor) ResourceMatch(allResources []v2action.Resource) ([]v2action.Resource, []v2action.Resource, v2action.Warnings, error) {
+ return r.wrapped.ResourceMatch(allResources)
+}
+
+func (r cfV2Actor) UnmapRouteFromApplication(routeGUID string, appGUID string) (v2action.Warnings, error) {
+ return r.wrapped.UnmapRouteFromApplication(routeGUID, appGUID)
+}
+
+func (r cfV2Actor) UpdateApplication(application v2action.Application) (v2action.Application, v2action.Warnings, error) {
+ r.sendAppID(application)
+ return r.wrapped.UpdateApplication(application)
+}
+
+func (r cfV2Actor) UploadApplicationPackage(appGUID string, existingResources []v2action.Resource, newResources io.Reader, newResourcesLength int64) (v2action.Job, v2action.Warnings, error) {
+ return r.wrapped.UploadApplicationPackage(appGUID, existingResources, newResources, newResourcesLength)
+}
+
+func (r cfV2Actor) UploadDroplet(appGUID string, droplet io.Reader, dropletLength int64) (v2action.Job, v2action.Warnings, error) {
+ return r.wrapped.UploadDroplet(appGUID, droplet, dropletLength)
+}
diff --git a/src/jetstream/plugins/cfapppush/pushapp.go b/src/jetstream/plugins/cfapppush/pushapp.go
new file mode 100644
index 0000000000..11a1c00976
--- /dev/null
+++ b/src/jetstream/plugins/cfapppush/pushapp.go
@@ -0,0 +1,401 @@
+package cfapppush
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+
+ "fmt"
+ "html/template"
+ "io"
+ "strings"
+
+ "code.cloudfoundry.org/cli/actor/pushaction"
+ "code.cloudfoundry.org/cli/actor/sharedaction"
+ "code.cloudfoundry.org/cli/actor/v2action"
+ "code.cloudfoundry.org/cli/actor/v2v3action"
+ "code.cloudfoundry.org/cli/actor/v3action"
+ "code.cloudfoundry.org/cli/cf/commandregistry"
+ "code.cloudfoundry.org/cli/command"
+
+ "code.cloudfoundry.org/cli/util/configv3"
+ "code.cloudfoundry.org/cli/util/progressbar"
+ "code.cloudfoundry.org/cli/util/ui"
+ "github.com/gorilla/websocket"
+
+ "code.cloudfoundry.org/cli/cf/flags"
+
+ "code.cloudfoundry.org/cli/command/flag"
+ "code.cloudfoundry.org/cli/command/translatableerror"
+ v6 "code.cloudfoundry.org/cli/command/v6"
+ "code.cloudfoundry.org/cli/command/v6/shared"
+ sharedV3 "code.cloudfoundry.org/cli/command/v6/shared"
+
+ "github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces"
+)
+
+// CFPushApp abstracts the push functionality form the CLI library
+type CFPushApp struct {
+ pushCommand *v6.PushCommand
+ flagContext flags.FlagContext
+ deps commandregistry.Dependency
+ config *CFPushAppConfig
+ portalProxy interfaces.PortalProxy
+}
+
+// CFPushAppConfig is the configuration used
+type CFPushAppConfig struct {
+ AuthorizationEndpoint string
+ CFClient string
+ CFClientSecret string
+ APIEndpointURL string
+ DopplerLoggingEndpoint string
+ SkipSSLValidation bool
+ AuthToken string
+ RefreshToken string
+ OrgGUID string
+ OrgName string
+ SpaceGUID string
+ SpaceName string
+ OutputWriter io.Writer
+ DialTimeout string
+}
+
+// CFPushAppOverrides represents the document that can be sent from the client with the app overrrides for the push
+type CFPushAppOverrides struct {
+ Name string `json:"name"`
+ Buildpack string `json:"buildpack"`
+ StartCmd string `json:"startCmd"`
+ HealthCheckType string `json:"healthCheckType"`
+ Stack string `json:"stack"`
+ Time *int `json:"time"`
+ Instances *int `json:"instances"`
+ DiskQuota string `json:"diskQuota"`
+ MemQuota string `json:"memQuota"`
+ DoNotStart bool `json:"doNotStart"`
+ NoRoute bool `json:"noRoute"`
+ RandomRoute bool `json:"randomRoute"`
+ Host string `json:"host"`
+ Domain string `json:"domain"`
+ Path string `json:"path"`
+ DockerImage string `json:"dockerImage"`
+ DockerUsername string `json:"dockerUsername"`
+}
+
+// DeployAppMessageSender is the interface for sending a message over a web socket
+type DeployAppMessageSender interface {
+ SendEvent(clientWebSocket *websocket.Conn, event MessageType, data string)
+}
+
+// ErrorType default error returned
+type ErrorType int
+
+const (
+ // GeneralFailure thrown when initialisation fails
+ GeneralFailure ErrorType = iota + 4000
+ // FailedToPush thrown when push fails
+ FailedToPush
+)
+
+// CFPush Interface
+type CFPush interface {
+ Init(appDir string, manifestPath string, overrides CFPushAppOverrides) error
+ Run(DeployAppMessageSender, *websocket.Conn) error
+}
+
+// PushError is the return error type from pushing
+type PushError struct {
+ error
+ Type ErrorType
+ Err error
+}
+
+func (p *PushError) Error() string {
+ return fmt.Sprintf("Push error: %s", p.Err)
+}
+
+// Constructor returns a CFPush based on the supplied config
+func Constructor(config *CFPushAppConfig, portalProxy interfaces.PortalProxy) CFPush {
+
+ pushCmd := &v6.PushCommand{}
+ cfPush := &CFPushApp{
+ pushCommand: pushCmd,
+ config: config,
+ portalProxy: portalProxy,
+ }
+ cfPush.init(config)
+ return cfPush
+}
+
+func (c *CFPushApp) init(config *CFPushAppConfig) error {
+ return nil
+}
+
+// Init initializes the push operation with the specified application directory and manifest path
+func (c *CFPushApp) Init(appDir string, manifestPath string, overrides CFPushAppOverrides) error {
+
+ // App name
+ if len(overrides.Name) > 0 {
+ c.pushCommand.OptionalArgs = flag.OptionalAppName{
+ AppName: overrides.Name,
+ }
+ }
+
+ // Buildpack - Note we only allow one buildpack to be specified as an override at present
+ if len(overrides.Buildpack) > 0 {
+ c.pushCommand.Buildpacks = make([]string, 1)
+ c.pushCommand.Buildpacks[0] = overrides.Buildpack
+ }
+
+ // Start Command
+ if len(overrides.StartCmd) > 0 {
+ c.pushCommand.Command = flag.Command{}
+ err := c.pushCommand.Command.UnmarshalFlag(overrides.StartCmd)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Domain
+ if len(overrides.Domain) > 0 {
+ c.pushCommand.Domain = overrides.Domain
+ }
+
+ // HealthCheckType
+ if len(overrides.HealthCheckType) > 0 {
+ err := c.pushCommand.HealthCheckType.UnmarshalFlag(overrides.HealthCheckType)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Hostname
+ if len(overrides.Host) > 0 {
+ c.pushCommand.Hostname = overrides.Host
+ }
+
+ // App instances
+ if overrides.Instances != nil {
+ c.pushCommand.Instances = flag.Instances{}
+ c.pushCommand.Instances.ParseIntValue(overrides.Instances)
+ }
+
+ // Disk Quota
+ if len(overrides.DiskQuota) > 0 {
+ c.pushCommand.DiskQuota = flag.Megabytes{}
+ err := c.pushCommand.DiskQuota.UnmarshalFlag(overrides.DiskQuota)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Memory Quota
+ if len(overrides.MemQuota) > 0 {
+ c.pushCommand.Memory = flag.Megabytes{}
+ err := c.pushCommand.Memory.UnmarshalFlag(overrides.MemQuota)
+ if err != nil {
+ return err
+ }
+ }
+
+ // No Route
+ c.pushCommand.NoRoute = overrides.NoRoute
+
+ // No start
+ c.pushCommand.NoStart = overrides.DoNotStart
+
+ // Random route
+ c.pushCommand.RandomRoute = overrides.RandomRoute
+
+ // Route path
+ if len(overrides.Path) > 0 {
+ c.pushCommand.RoutePath = flag.V6RoutePath{}
+ err := c.pushCommand.RoutePath.UnmarshalFlag(overrides.Path)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Stack
+ if len(overrides.Stack) > 0 {
+ c.pushCommand.StackName = overrides.Stack
+ }
+
+ // Health check time
+ if overrides.Time != nil {
+ c.pushCommand.HealthCheckTimeout = uint64(*overrides.Time)
+ }
+
+ // Docker image
+ if len(overrides.DockerImage) > 0 {
+ c.pushCommand.DockerImage = flag.DockerImage{
+ Path: overrides.DockerImage,
+ }
+ } else {
+ // App path can't be set with Docker Image
+ c.pushCommand.AppPath = flag.PathWithExistenceCheck(appDir)
+ }
+
+ // Docker username
+ if len(overrides.DockerUsername) > 0 {
+ c.pushCommand.DockerUsername = overrides.DockerUsername
+ }
+
+ // Manifest path
+ c.pushCommand.PathToManifest = flag.PathWithExistenceCheck(manifestPath)
+
+ return nil
+}
+
+// setConfig sets the org and space information
+func (c *CFPushApp) setConfig(config *configv3.Config) error {
+ config.SetOrganizationInformation(c.config.OrgGUID, c.config.OrgName)
+ config.SetSpaceInformation(c.config.SpaceGUID, c.config.SpaceName, false)
+ return nil
+}
+
+// Run performs the actual push
+func (c *CFPushApp) Run(msgSender DeployAppMessageSender, clientWebsocket *websocket.Conn) error {
+
+ // Get a CF Config
+ config, err := configv3.LoadConfig()
+ if err != nil {
+ return err
+ }
+
+ // Fetch and set endpoint info
+ err = c.setEndpointInfo(config)
+ if err != nil {
+ return err
+ }
+
+ commandUI, err := ui.NewUI(config)
+ if err != nil {
+ return err
+ }
+
+ commandUI.IsTTY = false
+ commandUI.TerminalWidth = 40
+
+ // Send logging to the front-end via the web-socket
+ commandUI.Out = c.config.OutputWriter
+ commandUI.Err = c.config.OutputWriter
+
+ defer commandUI.FlushDeferred()
+
+ err = c.setup(config, commandUI, msgSender, clientWebsocket)
+ //err = c.pushCommand.Setup(config, commandUI)
+ if err != nil {
+ return handleError(err, *commandUI)
+ }
+
+ // Update the config
+ err = c.setConfig(config)
+ if err != nil {
+ return handleError(err, *commandUI)
+ }
+
+ // Set to a null progress bar
+ c.pushCommand.ProgressBar = &cfPushProgressBar{}
+
+ // Perform the push
+ args := make([]string, 0)
+ err = c.pushCommand.Execute(args)
+ if err != nil {
+ return handleError(err, *commandUI)
+ }
+
+ return nil
+}
+
+func (push *CFPushApp) setup(config command.Config, ui command.UI, msgSender DeployAppMessageSender, clientWebsocket *websocket.Conn) error {
+ cmd := push.pushCommand
+ cmd.UI = ui
+ cmd.Config = config
+ sharedActor := sharedaction.NewActor(config)
+ cmd.SharedActor = sharedActor
+
+ ccClient, uaaClient, err := shared.GetNewClientsAndConnectToCF(config, ui)
+ if err != nil {
+ return err
+ }
+
+ ccClientV3, _, err := sharedV3.NewV3BasedClients(config, ui, true)
+ if err != nil {
+ return err
+ }
+
+ v2Actor := v2action.NewActor(ccClient, uaaClient, config)
+ v3Actor := v3action.NewActor(ccClientV3, config, sharedActor, nil)
+
+ stratosV2Actor := cfV2Actor{
+ wrapped: v2Actor,
+ msgSender: msgSender,
+ clientWebsocket: clientWebsocket,
+ }
+
+ cmd.RestartActor = v2Actor
+ cmd.Actor = pushaction.NewActor(stratosV2Actor, v3Actor, sharedActor)
+
+ cmd.ApplicationSummaryActor = v2v3action.NewActor(v2Actor, v3Actor)
+
+ cmd.NOAAClient = shared.NewNOAAClient(ccClient.DopplerEndpoint(), config, uaaClient, ui)
+
+ cmd.ProgressBar = progressbar.NewProgressBar()
+ return nil
+}
+
+// Simplified version of the CLI source
+func handleError(passedErr error, commandUI ui.UI) error {
+ if passedErr == nil {
+ return nil
+ }
+
+ translationFunc, _ := generateTranslationFunc([]byte("[]"))
+ translatedErr := translatableerror.ConvertToTranslatableError(passedErr)
+
+ var errMsg string
+ if translatableError, ok := translatedErr.(translatableerror.TranslatableError); ok {
+ errMsg = translatableError.Translate(translationFunc)
+
+ // Remove the TIP that might be at the end
+ parts := strings.Split(errMsg, "TIP:")
+ errMsg = strings.TrimSpace(parts[0])
+ } else {
+ errMsg = translatedErr.Error()
+ }
+
+ return errors.New(errMsg)
+}
+
+// Borrowed from the CLI source - its not exported, so we include it here
+func generateTranslationFunc(rawTranslation []byte) (ui.TranslateFunc, error) {
+ var entries []ui.TranslationEntry
+ err := json.Unmarshal(rawTranslation, &entries)
+ if err != nil {
+ return nil, err
+ }
+
+ translations := map[string]string{}
+ for _, entry := range entries {
+ translations[entry.ID] = entry.Translation
+ }
+
+ return func(translationID string, args ...interface{}) string {
+ translated := translations[translationID]
+ if translated == "" {
+ translated = translationID
+ }
+
+ var keys interface{}
+ if len(args) > 0 {
+ keys = args[0]
+ }
+
+ var buffer bytes.Buffer
+ formattedTemplate := template.Must(template.New("Display Text").Parse(translated))
+ formattedTemplate.Execute(&buffer, keys)
+
+ return buffer.String()
+ }, nil
+}
diff --git a/src/jetstream/plugins/cfapppush/pushapp/pushapp.go b/src/jetstream/plugins/cfapppush/pushapp/pushapp.go
deleted file mode 100644
index 801b79751b..0000000000
--- a/src/jetstream/plugins/cfapppush/pushapp/pushapp.go
+++ /dev/null
@@ -1,309 +0,0 @@
-package pushapp
-
-import (
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strconv"
- "time"
-
- "code.cloudfoundry.org/cli/cf/api/applications"
-
- "code.cloudfoundry.org/cli/cf/actors"
- "code.cloudfoundry.org/cli/cf/actors/brokerbuilder"
- "code.cloudfoundry.org/cli/cf/actors/planbuilder"
- "code.cloudfoundry.org/cli/cf/actors/pluginrepo"
- "code.cloudfoundry.org/cli/cf/actors/servicebuilder"
- "code.cloudfoundry.org/cli/cf/api"
- "code.cloudfoundry.org/cli/cf/appfiles"
- "code.cloudfoundry.org/cli/cf/commandregistry"
- "code.cloudfoundry.org/cli/cf/configuration"
- "code.cloudfoundry.org/cli/cf/configuration/confighelpers"
- "code.cloudfoundry.org/cli/cf/configuration/coreconfig"
- "code.cloudfoundry.org/cli/cf/configuration/pluginconfig"
- "code.cloudfoundry.org/cli/cf/manifest"
- "code.cloudfoundry.org/cli/cf/models"
- "code.cloudfoundry.org/cli/cf/net"
- "code.cloudfoundry.org/cli/cf/terminal"
- "code.cloudfoundry.org/cli/cf/trace"
- "code.cloudfoundry.org/cli/util"
- "code.cloudfoundry.org/cli/util/randomword"
- uuid "github.com/satori/go.uuid"
- log "github.com/sirupsen/logrus"
-
- "code.cloudfoundry.org/cli/cf/commands/application"
- "code.cloudfoundry.org/cli/cf/flags"
-)
-
-// CFPushApp abstracts the push functionality form the CLI library
-type CFPushApp struct {
- pushCommand *application.Push
- flagContext flags.FlagContext
- deps commandregistry.Dependency
-}
-
-// CFPushAppConfig is the configuration used
-type CFPushAppConfig struct {
- AuthorizationEndpoint string
- CFClient string
- CFClientSecret string
- APIEndpointURL string
- DopplerLoggingEndpoint string
- SkipSSLValidation bool
- AuthToken string
- RefreshToken string
- OrgGUID string
- OrgName string
- SpaceGUID string
- SpaceName string
- OutputWriter io.Writer
- DialTimeout string
-}
-
-type CFPushAppOverrides struct {
- Name string `json:"name"`
- Buildpack string `json:"buildpack"`
- StartCmd string `json:"startCmd"`
- HealthCheckType string `json:"healthCheckType"`
- Stack string `json:"stack"`
- Time *int `json:"time"`
- Instances *int `json:"instances"`
- DiskQuota string `json:"diskQuota"`
- MemQuota string `json:"memQuota"`
- DoNotStart bool `json:"doNotStart"`
- NoRoute bool `json:"noRoute"`
- RandomRoute bool `json:"randomRoute"`
- Host string `json:"host"`
- Domain string `json:"domain"`
- Path string `json:"path"`
- DockerImage string `json:"dockerImage"`
- DockerUsername string `json:"dockerUsername"`
-}
-
-// ErrorType default error returned
-type ErrorType int
-
-const (
- // GeneralFailure thrown when initialisation fails
- GeneralFailure ErrorType = iota + 4000
- // FailedToPush thrown when push fails
- FailedToPush
-)
-
-// CFPush Interface
-type CFPush interface {
- Init(appDir string, manifestPath string, overrides CFPushAppOverrides) error
- Push() error
- GetDeps() commandregistry.Dependency
- PatchApplicationRepository(repo applications.Repository)
-}
-
-// PushError is the return error type from pushing
-type PushError struct {
- error
- Type ErrorType
- Err error
-}
-
-func (p *PushError) Error() string {
- return fmt.Sprintf("Push error: %s", p.Err)
-}
-
-// Constructor returns a CFPush based on the supplied config
-func Constructor(config *CFPushAppConfig) CFPush {
-
- pushCmd := &application.Push{}
- metaData := pushCmd.MetaData()
- flagContext := flags.NewFlagContext(metaData.Flags)
-
- cfPush := &CFPushApp{
- pushCommand: pushCmd,
- flagContext: flagContext,
- }
- cfPush.init(config)
- return cfPush
-
-}
-
-func (c *CFPushApp) init(config *CFPushAppConfig) error {
- uuid := uuid.NewV4()
- var filePath = fmt.Sprintf("/tmp/%s", uuid)
- repo := coreconfig.NewRepositoryFromFilepath(filePath, func(error) {})
- repo.SetAuthenticationEndpoint(config.AuthorizationEndpoint)
- repo.SetUAAOAuthClient(config.CFClient)
- repo.SetUAAOAuthClientSecret(config.CFClientSecret)
- repo.SetAPIEndpoint(config.APIEndpointURL)
- repo.SetDopplerEndpoint(config.DopplerLoggingEndpoint)
- repo.SetSSLDisabled(config.SkipSSLValidation)
- repo.SetAccessToken(config.AuthToken)
- repo.SetRefreshToken(config.RefreshToken)
- repo.SetColorEnabled("true")
- repo.SetOrganizationFields(models.OrganizationFields{
- GUID: config.OrgGUID,
- Name: config.OrgName,
- })
- repo.SetSpaceFields(models.SpaceFields{
- GUID: config.SpaceGUID,
- Name: config.SpaceName,
- })
- traceLogger := trace.NewLogger(os.Stdout, true)
- dialTimeout := config.DialTimeout
- c.deps = initialiseDependency(config.OutputWriter, traceLogger, dialTimeout, repo)
- return nil
-}
-
-func initialiseDependency(writer io.Writer, logger trace.Printer, envDialTimeout string, config coreconfig.Repository) commandregistry.Dependency {
-
- deps := commandregistry.Dependency{}
- deps.TeePrinter = terminal.NewTeePrinter(writer)
- deps.UI = terminal.NewUI(os.Stdin, writer, deps.TeePrinter, logger)
-
- errorHandler := func(err error) {
- if err != nil {
- deps.UI.Failed(fmt.Sprintf("Config error: %s", err))
- }
- }
-
- deps.Config = config
-
- deps.ManifestRepo = manifest.NewDiskRepository()
- deps.AppManifest = manifest.NewGenerator()
-
- pluginPath := filepath.Join(confighelpers.PluginRepoDir(), ".cf", "plugins")
- deps.PluginConfig = pluginconfig.NewPluginConfig(
- errorHandler,
- configuration.NewDiskPersistor(filepath.Join(pluginPath, "config.json")),
- pluginPath,
- )
-
- terminal.UserAskedForColors = deps.Config.ColorEnabled()
- terminal.InitColorSupport()
-
- deps.Gateways = map[string]net.Gateway{
- "cloud-controller": net.NewCloudControllerGateway(deps.Config, time.Now, deps.UI, logger, envDialTimeout),
- "uaa": net.NewUAAGateway(deps.Config, deps.UI, logger, envDialTimeout),
- "routing-api": net.NewRoutingAPIGateway(deps.Config, time.Now, deps.UI, logger, envDialTimeout),
- }
- deps.RepoLocator = api.NewRepositoryLocator(deps.Config, deps.Gateways, logger, envDialTimeout)
-
- deps.PluginModels = &commandregistry.PluginModels{Application: nil}
-
- deps.PlanBuilder = planbuilder.NewBuilder(
- deps.RepoLocator.GetServicePlanRepository(),
- deps.RepoLocator.GetServicePlanVisibilityRepository(),
- deps.RepoLocator.GetOrganizationRepository(),
- )
-
- deps.ServiceBuilder = servicebuilder.NewBuilder(
- deps.RepoLocator.GetServiceRepository(),
- deps.PlanBuilder,
- )
-
- deps.BrokerBuilder = brokerbuilder.NewBuilder(
- deps.RepoLocator.GetServiceBrokerRepository(),
- deps.ServiceBuilder,
- )
-
- deps.PluginRepo = pluginrepo.NewPluginRepo()
-
- deps.ServiceHandler = actors.NewServiceHandler(
- deps.RepoLocator.GetOrganizationRepository(),
- deps.BrokerBuilder,
- deps.ServiceBuilder,
- )
-
- deps.ServicePlanHandler = actors.NewServicePlanHandler(
- deps.RepoLocator.GetServicePlanRepository(),
- deps.RepoLocator.GetServicePlanVisibilityRepository(),
- deps.RepoLocator.GetOrganizationRepository(),
- deps.PlanBuilder,
- deps.ServiceBuilder,
- )
-
- deps.WordGenerator = new(randomword.Generator)
-
- deps.AppZipper = appfiles.ApplicationZipper{}
- deps.AppFiles = appfiles.ApplicationFiles{}
-
- deps.RouteActor = actors.NewRouteActor(deps.UI, deps.RepoLocator.GetRouteRepository(), deps.RepoLocator.GetDomainRepository())
- deps.PushActor = actors.NewPushActor(deps.RepoLocator.GetApplicationBitsRepository(), deps.AppZipper, deps.AppFiles, deps.RouteActor)
-
- deps.ChecksumUtil = util.NewSha1Checksum("")
-
- deps.Logger = logger
-
- return deps
-
-}
-
-func appendFlag(flags []string, argName string, argValue string) []string {
- if len(argValue) != 0 {
- if len(argName) != 0 {
- return append(flags, argName, argValue)
- } else {
- return append(flags, argValue)
- }
- }
- return flags
-}
-
-// Init initializes the push operation with the specified application directory and manifest path
-func (c *CFPushApp) Init(appDir string, manifestPath string, overrides CFPushAppOverrides) error {
-
- var flags []string
-
- flags = appendFlag(flags, "", overrides.Name)
- flags = appendFlag(flags, "-b", overrides.Buildpack)
- flags = appendFlag(flags, "-c", overrides.StartCmd)
- flags = appendFlag(flags, "-d", overrides.Domain)
- flags = appendFlag(flags, "--health-check-type", overrides.HealthCheckType)
- flags = appendFlag(flags, "--hostname", overrides.Host)
- if overrides.Instances != nil {
- flags = append(flags, "-i", strconv.Itoa(*overrides.Instances))
- }
- flags = appendFlag(flags, "-k", overrides.DiskQuota)
- flags = appendFlag(flags, "-m", overrides.MemQuota)
- flags = append(flags, "--no-route", strconv.FormatBool(overrides.NoRoute))
- flags = append(flags, "--no-start", strconv.FormatBool(overrides.DoNotStart))
- flags = append(flags, "-p", appDir, "-f", manifestPath)
- flags = append(flags, "--random-route", strconv.FormatBool(overrides.RandomRoute))
- flags = appendFlag(flags, "--route-path", overrides.Path)
- flags = appendFlag(flags, "-s", overrides.Stack)
- if overrides.Time != nil {
- flags = append(flags, "-t", strconv.Itoa(*overrides.Time))
- }
- flags = appendFlag(flags, "--docker-image", overrides.DockerImage)
- flags = appendFlag(flags, "--docker-username", overrides.DockerUsername)
-
- log.Debugf("Cf Push Overrides: %v", flags)
-
- err := c.flagContext.Parse(flags...)
- if err != nil {
- return &PushError{Err: err, Type: GeneralFailure}
- }
- return nil
-}
-
-// GetDeps is used to install watcher
-func (c *CFPushApp) GetDeps() commandregistry.Dependency {
- return c.deps
-}
-
-// PatchApplicationRepository patches the repository locator so we can determine when the app has been created during push
-func (c *CFPushApp) PatchApplicationRepository(appRepo applications.Repository) {
- c.deps.RepoLocator = c.deps.RepoLocator.SetApplicationRepository(appRepo)
-}
-
-// Push starts the actual push process
-func (c *CFPushApp) Push() error {
-
- c.pushCommand.SetDependency(c.deps, false)
- defer c.deps.Config.Close()
-
- err := c.pushCommand.Execute(c.flagContext)
- if err != nil {
- return &PushError{Err: err, Type: FailedToPush}
- }
- return nil
-}
diff --git a/src/jetstream/plugins/cfapppush/types.go b/src/jetstream/plugins/cfapppush/types.go
index 34dc038dd3..650098c5e8 100644
--- a/src/jetstream/plugins/cfapppush/types.go
+++ b/src/jetstream/plugins/cfapppush/types.go
@@ -75,36 +75,30 @@ type MessageType int
// Based on manifest.rawManifestApplicaiton
type RawManifestApplication struct {
- Name string `yaml:"name,omitempty"`
- Buildpack string `yaml:"buildpack,omitempty"`
- Command string `yaml:"command,omitempty"`
- DeprecatedDomain interface{} `yaml:"domain,omitempty"`
- DeprecatedDomains interface{} `yaml:"domains,omitempty"`
- DeprecatedHost interface{} `yaml:"host,omitempty"`
- DeprecatedHosts interface{} `yaml:"hosts,omitempty"`
- DeprecatedNoHostname interface{} `yaml:"no-hostname,omitempty"`
- DiskQuota string `yaml:"disk_quota,omitempty"`
- Docker rawDockerInfo `yaml:"docker,omitempty"`
- DropletPath string `yaml:"droplet-path,omitempty"`
- EnvironmentVariables map[string]interface{} `yaml:"env,omitempty"`
- HealthCheckHTTPEndpoint string `yaml:"health-check-http-endpoint,omitempty"`
- HealthCheckType string `yaml:"health-check-type,omitempty"`
- Instances *int `yaml:"instances,omitempty"`
- Memory string `yaml:"memory,omitempty"`
- NoRoute bool `yaml:"no-route,omitempty"`
- Path string `yaml:"path,omitempty"`
- RandomRoute bool `yaml:"random-route,omitempty"`
- Routes []rawManifestRoute `yaml:"routes,omitempty"`
- Services []string `yaml:"services,omitempty"`
- StackName string `yaml:"stack,omitempty"`
- Timeout int `yaml:"timeout,omitempty"`
- DockerImage string `json:"docker_image,omitempty"`
- DockerCredentials DockerCredentials `json:"docker_credentials,omitempty"`
-}
-
-type DockerCredentials struct {
- Username string `json:"username"`
- Password string `json:"password"`
+ Name string `yaml:"name,omitempty"`
+ Buildpack string `yaml:"buildpack,omitempty"`
+ Buildpacks []string `yaml:"buildpacks,omitempty"`
+ Command string `yaml:"command,omitempty"`
+ DeprecatedDomain interface{} `yaml:"domain,omitempty"`
+ DeprecatedDomains interface{} `yaml:"domains,omitempty"`
+ DeprecatedHost interface{} `yaml:"host,omitempty"`
+ DeprecatedHosts interface{} `yaml:"hosts,omitempty"`
+ DeprecatedNoHostname interface{} `yaml:"no-hostname,omitempty"`
+ DiskQuota string `yaml:"disk_quota,omitempty"`
+ Docker rawDockerInfo `yaml:"docker,omitempty"`
+ DropletPath string `yaml:"droplet-path,omitempty"`
+ EnvironmentVariables map[string]string `yaml:"env,omitempty"`
+ HealthCheckHTTPEndpoint string `yaml:"health-check-http-endpoint,omitempty"`
+ HealthCheckType string `yaml:"health-check-type,omitempty"`
+ Instances *int `yaml:"instances,omitempty"`
+ Memory string `yaml:"memory,omitempty"`
+ NoRoute bool `yaml:"no-route,omitempty"`
+ Path string `yaml:"path,omitempty"`
+ RandomRoute bool `yaml:"random-route,omitempty"`
+ Routes []rawManifestRoute `yaml:"routes,omitempty"`
+ Services []string `yaml:"services,omitempty"`
+ StackName string `yaml:"stack,omitempty"`
+ Timeout int `yaml:"timeout,omitempty"`
}
type rawManifestRoute struct {
diff --git a/src/jetstream/repository/interfaces/structs.go b/src/jetstream/repository/interfaces/structs.go
index 6d6ef61d3c..041f2ebea0 100644
--- a/src/jetstream/repository/interfaces/structs.go
+++ b/src/jetstream/repository/interfaces/structs.go
@@ -20,6 +20,7 @@ type AuthProvider struct {
UserInfo GetUserInfoFromToken
}
+// V2Info is the response for the Cloud Foundry /v2/info API
type V2Info struct {
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
@@ -27,6 +28,10 @@ type V2Info struct {
AppSSHEndpoint string `json:"app_ssh_endpoint"`
AppSSHHostKeyFingerprint string `json:"app_ssh_host_key_fingerprint"`
AppSSHOauthCLient string `json:"app_ssh_oauth_client"`
+ APIVersion string `json:"api_version"`
+ RoutingEndpoint string `json:"routing_endpoint"`
+ MinCLIVersion string `json:"min_cli_version"`
+ MinRecommendedCLIVersion string `json:"min_recommended_cli_version"`
}
type InfoFunc func(apiEndpoint string, skipSSLValidation bool) (CNSIRecord, interface{}, error)
diff --git a/src/test-e2e/application/application-deploy-e2e.spec.ts b/src/test-e2e/application/application-deploy-e2e.spec.ts
index b351c0ac0d..ae241e4fa8 100644
--- a/src/test-e2e/application/application-deploy-e2e.spec.ts
+++ b/src/test-e2e/application/application-deploy-e2e.spec.ts
@@ -209,17 +209,27 @@ describe('Application Deploy -', () => {
appEvents.list.table.toggleSort('Timestamp');
const currentUser = e2e.secrets.getDefaultCFEndpoint().creds.nonAdmin.username;
- // Create
- expect(appEvents.list.table.getCell(0, 1).getText()).toBe('audit\napp\ncreate');
- expect(appEvents.list.table.getCell(0, 0).getText()).toBe(`person\n${currentUser}`);
- // Map Route
- expect(appEvents.list.table.getCell(1, 1).getText()).toBe('audit\napp\nmap-route');
- expect(appEvents.list.table.getCell(1, 0).getText()).toBe(`person\n${currentUser}`);
- // Update (route)
- expect(appEvents.list.table.getCell(2, 1).getText()).toBe('audit\napp\nupdate');
- expect(appEvents.list.table.getCell(2, 0).getText()).toBe(`person\n${currentUser}`);
- });
+ const checkEventTableItem = (data: { [columnHeader: string]: string }[], text) => {
+ const item = data.find(i => i.type === text);
+ expect(item).toBeDefined();
+ expect(item.actor).toBe(`person\n${currentUser}`);
+ };
+
+ // Don't worry about order of events
+ appEvents.list.table.getTableData().then(data => {
+ // Create
+ checkEventTableItem(data, 'audit\napp\ncreate');
+ // Lifecycle - buildpack(s)
+ checkEventTableItem(data, 'audit\napp\nupdate');
+ // Map Route
+ checkEventTableItem(data, 'audit\napp\nmap-route');
+ // Upload bits
+ checkEventTableItem(data, 'audit\napp\nupload-bits');
+ // Build Create
+ checkEventTableItem(data, 'audit\napp\nbuild\ncreate');
+ });
+ });
});
describe('Instance scaling', () => {
diff --git a/src/test-e2e/application/application-deploy-local-e2e.spec.ts b/src/test-e2e/application/application-deploy-local-e2e.spec.ts
index a97e018915..463e0b71cf 100644
--- a/src/test-e2e/application/application-deploy-local-e2e.spec.ts
+++ b/src/test-e2e/application/application-deploy-local-e2e.spec.ts
@@ -22,7 +22,7 @@ const spaceName = e2e.secrets.getDefaultCFEndpoint().testSpace;
let applicationZipFile;
-describe('Application Deploy - ', function () {
+describe('Application Deploy - ', () => {
const testAppName = ApplicationE2eHelper.createApplicationName();
const appDetails = {
cfGuid: '',
@@ -51,12 +51,12 @@ describe('Application Deploy - ', function () {
beforeAll(() => nav.goto(SideNavMenuItem.Applications));
// Might take a bit longer to deploy the app than the global default timeout allows
- beforeEach(function () {
+ beforeEach(() => {
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = newTimeout;
});
- afterEach(function () {
+ afterEach(() => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});