Uplift airshipctl version used in airshipui

Refactor the ctl package in airshipui to use latest changes to
config and phase packages in airshipctl.

Change-Id: I84f337eb0124cc7e1fc7b92b9acb178557bedc6b
This commit is contained in:
Matthew Fuller 2020-09-21 15:18:25 -07:00 committed by Bijaya Sharma
parent d3f5fe7601
commit 9a5e5ad0fb
15 changed files with 308 additions and 272 deletions

View File

@ -19,6 +19,15 @@
width: 20px;
}
.docless-phase {
padding-left: 20px;
}
.docless-phase-btn {
padding-left: 20px;
padding-right: 0px;
}
.phase-tree-invisible {
display: none;
}

View File

@ -17,10 +17,20 @@
<mat-icon class="grey-icon" svgIcon="doc"></mat-icon> {{node.name}}
</button>
</div>
<div *ngIf="node.isPhaseNode && node.hasError" class="phase-error">
<button mat-icon-button>
<mat-icon *ngIf="node.isPhaseNode && node.hasError" class="error-icon" svgIcon="error"></mat-icon> {{node.name}}
<div *ngIf="node.isPhaseNode && (node.hasError || node.children.length === 0)" class="phase-error">
<button *ngIf="node.hasError" mat-icon-button>
<mat-icon class="error-icon" svgIcon="error"></mat-icon> {{node.name}}
</button>
<div *ngIf="node.isPhaseNode && !node.hasError" class="docless-phase">
<button mat-button class="docless-phase-btn">{{node.name}}</button>
<button class="doc-btn" mat-icon-button (click)="viewPhaseDocs(node.id)"
matTooltip="View rendered documents"
matTooltipPosition="above"
matTooltipShowDelay="1000"
matTooltipHideDelay="500">
<mat-icon class="grey-icon" svgIcon="open_in_new"></mat-icon>
</button>
</div>
</div>
</div>
</li>

View File

@ -69,9 +69,6 @@ export class DocumentComponent implements WSReceiver {
case 'getPhaseTree':
this.handleGetPhaseTree(message.data);
break;
case 'getPhaseDocs':
this.handleGetPhaseDocs(message);
break;
case 'getYaml':
this.handleGetYaml(message);
break;
@ -91,13 +88,6 @@ export class DocumentComponent implements WSReceiver {
this.dataSource.data = this.phaseTree;
}
handleGetPhaseDocs(message: WebsocketMessage): void {
const tmp: KustomNode[] = [];
Object.assign(tmp, message.data);
this.cache[message.id] = tmp;
console.dir(this.cache[message.id]);
}
handleGetYaml(message: WebsocketMessage): void {
this.changeEditorContents((message.yaml));
this.setTitle(message.name);
@ -118,12 +108,6 @@ export class DocumentComponent implements WSReceiver {
this.editorTitle = str[str.length - 1];
}
refreshTreeData(): void {
const tmpdata = this.dataSource.data;
this.dataSource.data = null;
this.dataSource.data = tmpdata;
}
changeEditorContents(yaml: string): void {
this.code = atob(yaml);
}
@ -142,12 +126,6 @@ export class DocumentComponent implements WSReceiver {
this.websocketService.sendMessage(websocketMessage);
}
getPhaseDocs(id: string): void {
const websocketMessage = this.constructDocumentWsMessage('getPhaseDocs');
websocketMessage.id = id;
this.websocketService.sendMessage(websocketMessage);
}
viewPhaseDocs(id: string): void {
// show document viewer
}

View File

@ -1,5 +1,6 @@
export class KustomNode {
id: string;
phaseid: { name: string, namespace: string};
name: string;
canLoadChildren: boolean;
children: KustomNode[];

3
go.mod
View File

@ -9,11 +9,12 @@ require (
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.0.0
github.com/stretchr/testify v1.6.1
opendev.org/airship/airshipctl v0.0.0-20200812155702-f61953bcf558
opendev.org/airship/airshipctl v0.0.0-20200917132506-1660efc23150
sigs.k8s.io/kustomize/api v0.5.1
)
replace (
k8s.io/client-go => k8s.io/client-go v0.0.0-20191114101535-6c5935290e33
k8s.io/kubectl => k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.4.1
)

19
go.sum
View File

@ -512,6 +512,7 @@ github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEo
github.com/gophercloud/gophercloud v0.6.0 h1:Xb2lcqZtml1XjgYZxbeayEemq7ASbeTp09m36gQFpEU=
github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU=
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33 h1:893HsJqtxp9z1SF76gg6hY70hRY1wVlTSnC/h1yUDCo=
@ -627,6 +628,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/jsonnet-bundler/jsonnet-bundler v0.2.0/go.mod h1:/by7P/OoohkI3q4CgSFqcoFsVY+IaNbzOVDknEsKDeU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
@ -645,10 +647,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
@ -940,8 +944,10 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@ -1300,6 +1306,8 @@ golang.org/x/tools v0.0.0-20200327195553-82bb89366a1e/go.mod h1:Sl4aGygMT6LrqrWc
golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 h1:Xvf3ZQTm5bjXPxhI7g+dwqsCqadK1rcNtwtszuatetk=
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619210111-0f592d2728bb h1:/7SQoPdMxZ0c/Zu9tBJgMbRE/BmK6i9QXflNJXKAmw0=
golang.org/x/tools v0.0.0-20200619210111-0f592d2728bb/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@ -1363,6 +1371,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -1521,16 +1530,16 @@ modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
opendev.org/airship/airshipctl v0.0.0-20200812155702-f61953bcf558 h1:nCR2asZynFP5/7pLmSLBBdEMrL1mkMkfTd2lMsL8zuc=
opendev.org/airship/airshipctl v0.0.0-20200812155702-f61953bcf558/go.mod h1:x6OuTS7vmRVbNtPRqwVAqS1YuBvySsvWyVr6dvxq/Ic=
opendev.org/airship/airshipctl v0.0.0-20200917132506-1660efc23150 h1:tPr3sCzRipDWdRbIEWjr76x93MrwZRdk6Qt/5f4d6wg=
opendev.org/airship/airshipctl v0.0.0-20200917132506-1660efc23150/go.mod h1:VkcG7mjbe9zpyAgsAR8iLDpiJzofh9wqtteUtKhufYw=
opendev.org/airship/go-redfish v0.0.0-20200318103738-db034d1d753a h1:4ggAMTwpfu/w3ZXOIJ9tfYF37JIYn+eNCA4O10NduZ0=
opendev.org/airship/go-redfish v0.0.0-20200318103738-db034d1d753a/go.mod h1:FEjYcb3bYBWGpQIqtvVM0NrT5eyjlCOCj5JNf4lI+6s=
opendev.org/airship/go-redfish/client v0.0.0-20200318103738-db034d1d753a h1:S1dmsP5Cc6OQjAd6OgIKMcNPBiGjh5TDbijVjNE/VGU=
opendev.org/airship/go-redfish/client v0.0.0-20200318103738-db034d1d753a/go.mod h1:s0hwuUpBsRXOrhN0NR+fNVivXGyWgHKpqtyq7qYjpew=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
sigs.k8s.io/cli-utils v0.15.0 h1:QiGX8wfBaegKQhejZg2EsqCPYGtyavIpEjNTMdpzUlY=
sigs.k8s.io/cli-utils v0.15.0/go.mod h1:H35YA5iJIM7EVNgqDTjX2dgt4wE23zmnXOTSTlyD+PE=
sigs.k8s.io/cli-utils v0.18.1 h1:K4usJmMlI98mL+z+TdAnKfzng64/m8bRXZKPwy3ZCWw=
sigs.k8s.io/cli-utils v0.18.1/go.mod h1:B7KdqkSkHNIUn3cFbaR4aKUZMKtr+Benboi1w/HW/Fg=
sigs.k8s.io/cluster-api v0.3.5 h1:XPCuwrGL73x82a6spCHwkHHeGiQF+L4zntaoDg2qMzo=
sigs.k8s.io/cluster-api v0.3.5/go.mod h1:IoP66q4g92I/2f/9hltbE/FWG3RakIwRdYpY+6mqvtE=
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
@ -1541,10 +1550,8 @@ sigs.k8s.io/controller-tools v0.2.8/go.mod h1:9VKHPszmf2DHz/QmHkcfZoewO6BL7pPs9u
sigs.k8s.io/kind v0.7.1-0.20200303021537-981bd80d3802/go.mod h1:HIZ3PWUezpklcjkqpFbnYOqaqsAE1JeCTEwkgvPLXjk=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/api v0.3.1/go.mod h1:A+ATnlHqzictQfQC1q3KB/T6MSr0UWQsrrLxMWkge2E=
sigs.k8s.io/kustomize/api v0.5.1 h1:iHGTs5LcnJGqHstUSxWD/kX6XZgmd82x79LLlZwDU0I=
sigs.k8s.io/kustomize/api v0.5.1/go.mod h1:LGqJ9ZWOnWDqlECqrFgNUyEqSJc6ooA9ZiWZ4KFZv+I=
sigs.k8s.io/kustomize/kyaml v0.1.4/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE=
sigs.k8s.io/kustomize/kyaml v0.4.1 h1:NEqA/35upoAjb+I5vh1ODUqxoX4DOrezeQa9BhhG5Co=
sigs.k8s.io/kustomize/kyaml v0.4.1/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=

View File

@ -106,18 +106,16 @@ const (
Validate WsSubComponentType = "validate"
// ctl components
GetDefaults WsSubComponentType = "getDefaults"
GenerateISO WsSubComponentType = "generateISO"
DocPull WsSubComponentType = "docPull"
Yaml WsSubComponentType = "yaml"
YamlWrite WsSubComponentType = "yamlWrite"
GetYaml WsSubComponentType = "getYaml"
GetSource WsSubComponentType = "getSource"
GetRendered WsSubComponentType = "getRendered"
GetPhaseTree WsSubComponentType = "getPhaseTree"
GetPhaseSourceFiles WsSubComponentType = "getPhaseSource"
GetPhaseDocuments WsSubComponentType = "getPhaseDocs"
GetTarget WsSubComponentType = "getTarget"
GetDefaults WsSubComponentType = "getDefaults"
GenerateISO WsSubComponentType = "generateISO"
DocPull WsSubComponentType = "docPull"
Yaml WsSubComponentType = "yaml"
YamlWrite WsSubComponentType = "yamlWrite"
GetYaml WsSubComponentType = "getYaml"
GetSource WsSubComponentType = "getSource"
GetRendered WsSubComponentType = "getRendered"
GetPhaseTree WsSubComponentType = "getPhaseTree"
GetTarget WsSubComponentType = "getTarget"
)
// WsMessage is a request / return structure used for websockets
@ -143,11 +141,9 @@ type WsMessage struct {
Authentication *Authentication `json:"authentication,omitempty"`
// information related to the init of the UI
Dashboards []Dashboard `json:"dashboards,omitempty"`
AuthMethod *AuthMethod `json:"authMethod,omitempty"`
AuthInfoOptions *config.AuthInfoOptions `json:"authInfoOptions,omitempty"`
ContextOptions *config.ContextOptions `json:"contextOptions,omitempty"`
ClusterOptions *config.ClusterOptions `json:"clusterOptions,omitempty"`
Dashboards []Dashboard `json:"dashboards,omitempty"`
AuthMethod *AuthMethod `json:"authMethod,omitempty"`
ContextOptions *config.ContextOptions `json:"contextOptions,omitempty"`
}
// SetUIConfig sets the UIConfig object with values obtained from

View File

@ -15,13 +15,21 @@
package ctl
import (
"opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/log"
"opendev.org/airship/airshipui/pkg/configs"
uiLog "opendev.org/airship/airshipui/pkg/log"
"opendev.org/airship/airshipui/pkg/webservice"
)
// AirshipConfigPath location of airship config (default $HOME/.airship.config)
// TODO(mfuller): are we going to retrieve these from the environment / cli options?
// leaving them both unset (nil) for now so that the default locations will be used
var AirshipConfigPath *string
// KubeConfigPath location of kubeconfig used by airshipctl (default $HOME/.airship/kubeconfig)
var KubeConfigPath *string
// CTLFunctionMap is a function map for the CTL functions that is referenced in the webservice
var CTLFunctionMap = map[configs.WsComponentType]func(configs.WsMessage) configs.WsMessage{
configs.Baremetal: HandleBaremetalRequest,
@ -34,7 +42,8 @@ var runningRequests map[configs.WsSubComponentType]bool = make(map[configs.WsSub
// Client provides a library of functions that enable external programs (e.g. Airship UI) to perform airshipctl
// functionality in exactly the same manner as the CLI.
type Client struct {
settings *environment.AirshipCTLSettings
Config *config.Config
Debug bool // this is a placeholder until I figure out how / where to set this in airshipctl
}
// LogInterceptor is just a struct to hold a pointer to the remote channel
@ -52,31 +61,36 @@ func Init() {
}
// NewDefaultClient initializes the airshipctl client for external usage with default logging.
func NewDefaultClient() *Client {
settings := &environment.AirshipCTLSettings{}
// ensure no error if airship config doesn't exist
settings.Create = true
settings.InitConfig()
func NewDefaultClient(airshipConfigPath, kubeConfigPath *string) (*Client, error) {
cfgFactory := config.CreateFactory(airshipConfigPath, kubeConfigPath)
client := &Client{
settings: settings,
conf, err := cfgFactory()
if err != nil {
return nil, err
}
// set verbosity to true
client.settings.Debug = true
client := &Client{
Config: conf,
}
return client
// TODO(mfuller): how do you do this now?
// set verbosity to true
return client, nil
}
// NewClient initializes the airshipctl client for external usage with the logging overridden.
func NewClient(request configs.WsMessage) *Client {
client := NewDefaultClient()
func NewClient(airshipConfigPath, kubeConfigPath *string, request configs.WsMessage) (*Client, error) {
client, err := NewDefaultClient(airshipConfigPath, kubeConfigPath)
if err != nil {
return nil, err
}
// init the interceptor to send messages to the UI
// TODO: Unsure how this will be handled with overlapping runs
log.Init(client.settings.Debug, NewLogInterceptor(request))
log.Init(client.Debug, NewLogInterceptor(request))
return client
return client, nil
}
// NewLogInterceptor will construct a channel writer for use with the logger

View File

@ -18,6 +18,7 @@ import (
"fmt"
"opendev.org/airship/airshipctl/pkg/bootstrap/isogen"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipui/pkg/configs"
)
@ -32,13 +33,19 @@ func HandleBaremetalRequest(request configs.WsMessage) configs.WsMessage {
var err error
var message string
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
if err != nil {
response.Error = err.Error()
return response
}
subComponent := request.SubComponent
switch subComponent {
case configs.GenerateISO:
// since this is long running cache it up
// TODO: Test before running the geniso
runningRequests[subComponent] = true
client := NewClient(request)
message, err = client.generateIso()
// now that we're done forget we did anything
delete(runningRequests, subComponent)
@ -57,7 +64,8 @@ func HandleBaremetalRequest(request configs.WsMessage) configs.WsMessage {
func (c *Client) generateIso() (string, error) {
var message string
err := isogen.GenerateBootstrapIso(c.settings)
cfgFactory := config.CreateFactory(AirshipConfigPath, KubeConfigPath)
err := isogen.GenerateBootstrapIso(cfgFactory)
if err == nil {
message = fmt.Sprintf("Success")
}

View File

@ -28,6 +28,12 @@ func TestHandleUnknownBaremetalSubComponent(t *testing.T) {
SubComponent: "fake_subcomponent",
}
acp := "testdata/testairshipconfig"
kcp := "testdata/testkubeconfig"
AirshipConfigPath = &acp
KubeConfigPath = &kcp
response := HandleBaremetalRequest(request)
expected := configs.WsMessage{

View File

@ -21,6 +21,7 @@ import (
"os"
"path/filepath"
"opendev.org/airship/airshipctl/pkg/config"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/document/pull"
"opendev.org/airship/airshipui/pkg/configs"
@ -42,7 +43,11 @@ func HandleDocumentRequest(request configs.WsMessage) configs.WsMessage {
var message string
var id string
client := NewClient(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
if err != nil {
response.Error = err.Error()
return response
}
switch request.SubComponent {
case configs.DocPull:
@ -56,12 +61,6 @@ func HandleDocumentRequest(request configs.WsMessage) configs.WsMessage {
response.Name, response.YAML, err = client.getYaml(id)
case configs.GetPhaseTree:
response.Data, err = client.GetPhaseTree()
case configs.GetPhaseDocuments:
id = request.ID
response.Data, err = GetPhaseDocuments(request.ID)
case configs.GetPhaseSourceFiles:
id = request.ID
response.Data, err = client.GetPhaseSourceFiles(request.ID)
case configs.GetTarget:
message = client.getTarget()
default:
@ -79,7 +78,7 @@ func HandleDocumentRequest(request configs.WsMessage) configs.WsMessage {
}
func (c *Client) getTarget() string {
m, err := c.settings.Config.CurrentContextManifest()
m, err := c.Config.CurrentContextManifest()
if err != nil {
return "unknown"
}
@ -110,7 +109,7 @@ func getDocumentYaml(doc document.Document) (string, string, error) {
}
func (c *Client) getFileYaml(path string) (string, string, error) {
ccm, err := c.settings.Config.CurrentContextManifest()
ccm, err := c.Config.CurrentContextManifest()
if err != nil {
return "", "", err
}
@ -163,8 +162,8 @@ func (c *Client) writeYamlFile(id, yaml64 string) (string, string, error) {
func (c *Client) docPull() (string, error) {
var message string
settings := pull.Settings{AirshipCTLSettings: c.settings}
err := settings.Pull()
cfgFactory := config.CreateFactory(AirshipConfigPath, KubeConfigPath)
err := pull.Pull(cfgFactory)
if err == nil {
message = fmt.Sprintf("Success")
}

View File

@ -28,6 +28,12 @@ func TestHandleUnknownDocumentSubComponent(t *testing.T) {
SubComponent: "fake_subcomponent",
}
acp := "testdata/testairshipconfig"
kcp := "testdata/testkubeconfig"
AirshipConfigPath = &acp
KubeConfigPath = &kcp
response := HandleDocumentRequest(request)
expected := configs.WsMessage{

37
pkg/ctl/testdata/testairshipconfig vendored Normal file
View File

@ -0,0 +1,37 @@
apiVersion: airshipit.org/v1alpha1
contexts:
dummy_context:
contextKubeconf: dummy_cluster_ephemeral
encryptionConfig: dummy_encryption_config
managementConfiguration: dummy_management_config
manifest: dummy_manifest
currentContext: dummy_context
encryptionConfigs:
dummy_encryption_config:
decryptionKeyPath: /tmp/decryption.pub
encryptionKeyPath: /tmp/encryption.key
kind: Config
managementConfiguration:
dummy_management_config:
insecure: true
type: redfish
manifests:
dummy_manifest:
metadataPath: manifests/site/test-site/metadata.yaml
primaryRepositoryName: primary
repositories:
primary:
auth:
sshKey: testdata/test-key.pem
type: ssh-key
checkout:
branch: ""
commitHash: ""
force: false
tag: v1.0.1
url: http://dummy.url.com/manifests.git
subPath: manifests/site/test-site
targetPath: /var/tmp/
permissions:
DirectoryPermission: 488
FilePermission: 416

57
pkg/ctl/testdata/testkubeconfig vendored Normal file
View File

@ -0,0 +1,57 @@
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: http://5.6.7.8
name: def_ephemeral
- cluster:
insecure-skip-tls-verify: true
server: http://1.2.3.4
name: def_target
- cluster:
insecure-skip-tls-verify: true
server: http://9.10.11.12
name: onlyinkubeconf_target
- cluster:
certificate-authority: cert_file
server: ""
name: wrongonlyinkubeconf_target
- cluster:
insecure-skip-tls-verify: true
server: http://9.10.11.12
name: invalidName
- cluster:
insecure-skip-tls-verify: true
server: http://9.10.11.12
name: clustertypenil_target
contexts:
- context:
cluster: def_ephemeral
user: k-admin
name: def_ephemeral
- context:
cluster: def_target
user: k-admin
name: def_target
- context:
cluster: onlyinkubeconf_target
user: k-other
name: onlyink
current-context: ""
kind: Config
preferences: {}
users:
users:
- name: def-user
user:
username: dummy_username
password: ZHVtbXlfcGFzc3dvcmQK
- name: k-admin
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
- name: k-other
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

View File

@ -23,64 +23,31 @@ import (
"strings"
"github.com/google/uuid"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/ifc"
"opendev.org/airship/airshipui/pkg/log"
"sigs.k8s.io/kustomize/api/types"
)
var phaseIndex map[string]PhaseObj = buildPhaseIndex()
// TODO(mfuller): new helper each time? or once here?
var helper ifc.Helper
// PhaseObj lightweight structure to hold the name and document
// entrypoint for airshipctl phases
type PhaseObj struct {
Group string
Name string
Entrypoint string
}
func getHelper() (ifc.Helper, error) {
if helper != nil {
return helper, nil
}
func buildPhaseIndex() map[string]PhaseObj {
client := NewDefaultClient()
return client.buildPhaseIndex()
}
func (client *Client) buildPhaseIndex() map[string]PhaseObj {
idx := map[string]PhaseObj{}
// get target path from ctl settings
tp, err := client.settings.Config.CurrentContextTargetPath()
c, err := NewDefaultClient(AirshipConfigPath, KubeConfigPath)
if err != nil {
log.Errorf("Error building phase index: %s", err)
return nil
return nil, err
}
cmd := phase.Cmd{AirshipCTLSettings: client.settings}
plan, err := cmd.Plan()
h, err := phase.NewHelper(c.Config)
if err != nil {
log.Errorf("Error building phase index: %s", err)
return nil
return nil, err
}
for grp, phases := range plan {
for _, phase := range phases {
p, err := cmd.GetPhase(phase)
if err != nil {
log.Errorf("Error building phase index: %s", err)
return nil
}
entrypoint := fmt.Sprintf("%s/kustomization.yaml",
filepath.Join(tp, p.Config.DocumentEntryPoint))
idx[uuid.New().String()] = PhaseObj{
Group: grp,
Name: phase,
Entrypoint: entrypoint,
}
}
}
return idx
return h, nil
}
// GetPhaseTree builds the initial structure of the phase tree
@ -89,176 +56,115 @@ func (client *Client) buildPhaseIndex() map[string]PhaseObj {
func (client *Client) GetPhaseTree() ([]KustomNode, error) {
nodes := []KustomNode{}
grpMap := map[string][]KustomNode{}
for id, po := range phaseIndex {
pNode := KustomNode{
ID: id,
Name: fmt.Sprintf("Phase: %s", po.Name),
IsPhaseNode: true,
}
children, err := client.GetPhaseSourceFiles(id)
if err != nil {
// TODO(mfuller): push an error to UI so it can be handled by
// toastr service, pending refactor of webservice and configs pkgs
log.Errorf("Error building tree for phase '%s': %s", po.Name, err)
pNode.HasError = true
} else {
pNode.Children = children
}
grpMap[po.Group] = append(grpMap[po.Group], pNode)
helper, err := getHelper()
if err != nil {
return nil, err
}
for name, phases := range grpMap {
gNode := KustomNode{
ID: uuid.New().String(),
Name: fmt.Sprintf("Group: %s", name),
Children: phases,
phases, err := helper.ListPhases()
if err != nil {
return nil, err
}
for _, p := range phases {
pNode := KustomNode{
ID: uuid.New().String(),
PhaseID: ifc.ID{Name: p.Name, Namespace: p.Namespace},
Name: fmt.Sprintf("Phase: %s", p.Name),
IsPhaseNode: true,
Children: []KustomNode{},
}
nodes = append(nodes, gNode)
// some phases don't have any associated documents, so don't look
// for children unless a DocumentEntryPoint has been specified
if p.Config.DocumentEntryPoint != "" {
children, err := client.GetPhaseSourceFiles(pNode.PhaseID)
if err != nil {
// TODO(mfuller): push an error to UI so it can be handled by
// toastr service, pending refactor of webservice and configs pkgs
log.Errorf("Error building tree for phase '%s': %s", p.Name, err)
pNode.HasError = true
} else {
pNode.Children = children
}
}
nodes = append(nodes, pNode)
}
return nodes, nil
}
// GetPhaseDocuments returns a slice of KustomNodes representing
// all of the rendered documents making up a phase bundle.
// Ordering is k8s Namespace -> k8s Kind -> document name
func GetPhaseDocuments(id string) ([]KustomNode, error) {
if index == nil {
index = map[string]interface{}{}
}
nsNodes := []KustomNode{}
if p, ok := phaseIndex[id]; ok {
// get map of all docs associated with this bundle
docs, err := sortDocuments(p.Entrypoint)
if err != nil {
return nil, err
}
// namespace node
for ns, kinds := range docs {
nsNode := KustomNode{
ID: uuid.New().String(),
Name: ns,
Children: []KustomNode{},
}
// kind node
for kind, docs := range kinds {
kNode := KustomNode{
ID: uuid.New().String(),
Name: kind,
Children: []KustomNode{},
}
// doc node
for _, d := range docs {
id := uuid.New().String()
dNode := KustomNode{
ID: id,
Name: d.GetName(),
}
index[id] = d
kNode.Children = append(kNode.Children, dNode)
}
nsNode.Children = append(nsNode.Children, kNode)
}
nsNodes = append(nsNodes, nsNode)
}
}
return nsNodes, nil
}
// sort a bundle's docs into namespace, kind
func sortDocuments(path string) (map[string]map[string][]document.Document, error) {
docMap := map[string]map[string][]document.Document{}
bundle, err := document.NewBundleByPath(filepath.Dir(path))
if err != nil {
return nil, err
}
docs, err := bundle.GetAllDocuments()
if err != nil {
return nil, err
}
for _, doc := range docs {
ns := doc.GetNamespace()
if ns == "" {
ns = "[no namespace]"
}
kind := doc.GetKind()
if docMap[ns] == nil {
docMap[ns] = map[string][]document.Document{}
}
docMap[ns][kind] = append(docMap[ns][kind], doc)
}
return docMap, nil
}
// GetPhaseSourceFiles returns a slice of KustomNodes representing
// all of the directories that will be traversed when kustomize
// builds the document bundle. The tree hierarchy is:
// kustomize "type" (like function) -> directory name -> file name
func (client *Client) GetPhaseSourceFiles(id string) ([]KustomNode, error) {
func (client *Client) GetPhaseSourceFiles(id ifc.ID) ([]KustomNode, error) {
if index == nil {
index = map[string]interface{}{}
}
helper, err := getHelper()
if err != nil {
return nil, err
}
phase, err := helper.Phase(id)
if err != nil {
return nil, err
}
dirs, err := getKustomizeDirs(
filepath.Join(helper.TargetPath(),
phase.Config.DocumentEntryPoint,
"kustomization.yaml"))
if err != nil {
return nil, err
}
dm, err := client.createDirsMap(dirs)
if err != nil {
return nil, err
}
dirNodes := []KustomNode{}
if p, ok := phaseIndex[id]; ok {
dirs, err := getKustomizeDirs(p.Entrypoint)
if err != nil {
return nil, err
// kustomize "type" node
for t, data := range dm {
tNode := KustomNode{
ID: uuid.New().String(),
Name: t,
}
dm, err := client.createDirsMap(dirs)
if err != nil {
return nil, err
}
// kustomize "type" node
for t, data := range dm {
tNode := KustomNode{
ID: uuid.New().String(),
Name: t,
// directory node
for _, d := range data {
name := d[0]
abs := d[1]
dNode := KustomNode{
ID: uuid.New().String(),
Name: name,
Children: []KustomNode{},
}
// directory node
for _, d := range data {
name := d[0]
abs := d[1]
dNode := KustomNode{
ID: uuid.New().String(),
Name: name,
Children: []KustomNode{},
}
files, err := ioutil.ReadDir(abs)
if err != nil {
return nil, err
}
// file (leaf) node
for _, f := range files {
if !f.IsDir() {
id := uuid.New().String()
path := filepath.Join(abs, f.Name())
dNode.Children = append(dNode.Children,
KustomNode{
ID: id,
Name: f.Name(),
})
index[id] = path
}
}
tNode.Children = append(tNode.Children, dNode)
files, err := ioutil.ReadDir(abs)
if err != nil {
return nil, err
}
dirNodes = append(dirNodes, tNode)
// file (leaf) node
for _, f := range files {
if !f.IsDir() {
id := uuid.New().String()
path := filepath.Join(abs, f.Name())
dNode.Children = append(dNode.Children,
KustomNode{
ID: id,
Name: f.Name(),
})
index[id] = path
}
}
tNode.Children = append(tNode.Children, dNode)
}
dirNodes = append(dirNodes, tNode)
}
return dirNodes, nil
}
@ -266,7 +172,8 @@ func (client *Client) GetPhaseSourceFiles(id string) ([]KustomNode, error) {
// KustomNode structure to represent the kustomization tree for a given phase
// bundle to be consumed by the UI frontend
type KustomNode struct {
ID string `json:"id"` // UUID for backend node index
ID string `json:"id"` // UUID for backend node index
PhaseID ifc.ID `json:"phaseid"`
Name string `json:"name"` // name used for display purposes (cli, ui)
IsPhaseNode bool `json:"isPhaseNode"`
HasError bool `json:"hasError"`
@ -332,7 +239,7 @@ func getKustomizeDirs(entrypoint string) ([]string, error) {
func (client *Client) createDirsMap(dirs []string) (map[string][][]string, error) {
dm := map[string][][]string{}
tp, err := client.settings.Config.CurrentContextTargetPath()
tp, err := client.Config.CurrentContextTargetPath()
if err != nil {
return nil, err
}