forked from p15670423/monkey
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
2f1e690c21
|
@ -1,810 +0,0 @@
|
||||||
.vis .overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
/* Must be displayed above for example selected Timeline items */
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis-active {
|
|
||||||
box-shadow: 0 0 10px #86d5f8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* override some bootstrap styles screwing up the timelines css */
|
|
||||||
|
|
||||||
.vis [class*="span"] {
|
|
||||||
min-height: 0;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline.root {
|
|
||||||
position: relative;
|
|
||||||
border: 1px solid #bfbfbf;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel.center,
|
|
||||||
.vis.timeline .vispanel.left,
|
|
||||||
.vis.timeline .vispanel.right,
|
|
||||||
.vis.timeline .vispanel.top,
|
|
||||||
.vis.timeline .vispanel.bottom {
|
|
||||||
border: 1px #bfbfbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel.center,
|
|
||||||
.vis.timeline .vispanel.left,
|
|
||||||
.vis.timeline .vispanel.right {
|
|
||||||
border-top-style: solid;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel.center,
|
|
||||||
.vis.timeline .vispanel.top,
|
|
||||||
.vis.timeline .vispanel.bottom {
|
|
||||||
border-left-style: solid;
|
|
||||||
border-right-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .background {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel > .content {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel .shadow {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.8);
|
|
||||||
/* TODO: find a nice way to ensure shadows are drawn on top of items
|
|
||||||
z-index: 1;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel .shadow.top {
|
|
||||||
top: -1px;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel .shadow.bottom {
|
|
||||||
bottom: -1px;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .labelset {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .labelset .vlabel {
|
|
||||||
position: relative;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
color: #4d4d4d;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .labelset .vlabel {
|
|
||||||
border-bottom: 1px solid #bfbfbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .labelset .vlabel:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .labelset .vlabel .inner {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .labelset .vlabel .inner.hidden {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .itemset {
|
|
||||||
position: relative;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .itemset .background,
|
|
||||||
.vis.timeline .itemset .foreground {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .axis {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .foreground .group {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-bottom: 1px solid #bfbfbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .foreground .group:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .item {
|
|
||||||
position: absolute;
|
|
||||||
color: #1A1A1A;
|
|
||||||
border-color: #97B0F8;
|
|
||||||
border-width: 1px;
|
|
||||||
background-color: #D5DDF6;
|
|
||||||
display: inline-block;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.selected {
|
|
||||||
border-color: #FFC200;
|
|
||||||
background-color: #FFF785;
|
|
||||||
|
|
||||||
/* z-index must be higher than the z-index of custom time bar and current time bar */
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .editable .item.selected {
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.point.selected {
|
|
||||||
background-color: #FFF785;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.box {
|
|
||||||
text-align: center;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.point {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.dot {
|
|
||||||
position: absolute;
|
|
||||||
padding: 0;
|
|
||||||
border-width: 4px;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.range {
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 2px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.background {
|
|
||||||
overflow: hidden;
|
|
||||||
border: none;
|
|
||||||
background-color: rgba(213, 221, 246, 0.4);
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.range .content {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.background .content {
|
|
||||||
position: absolute;
|
|
||||||
display: inline-block;
|
|
||||||
overflow: hidden;
|
|
||||||
max-width: 100%;
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.line {
|
|
||||||
padding: 0;
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
border-left-width: 1px;
|
|
||||||
border-left-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item .content {
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item .delete {
|
|
||||||
background: url('img/timeline/delete.png') no-repeat top center;
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
top: 0;
|
|
||||||
right: -24px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.range .drag-left {
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
max-width: 20%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: -4px;
|
|
||||||
|
|
||||||
cursor: w-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.range .drag-right {
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
max-width: 20%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
right: -4px;
|
|
||||||
|
|
||||||
cursor: e-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis.foreground {
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis.background {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis .text {
|
|
||||||
position: absolute;
|
|
||||||
color: #4d4d4d;
|
|
||||||
padding: 3px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis .text.measure {
|
|
||||||
position: absolute;
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis .grid.vertical {
|
|
||||||
position: absolute;
|
|
||||||
border-left: 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis .grid.minor {
|
|
||||||
border-color: #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .timeaxis .grid.major {
|
|
||||||
border-color: #bfbfbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .currenttime {
|
|
||||||
background-color: #FF7F6E;
|
|
||||||
width: 2px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.vis.timeline .customtime {
|
|
||||||
background-color: #6E94FF;
|
|
||||||
width: 2px;
|
|
||||||
cursor: move;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.vis.timeline.root {
|
|
||||||
/*
|
|
||||||
-webkit-transition: height .4s ease-in-out;
|
|
||||||
transition: height .4s ease-in-out;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel {
|
|
||||||
/*
|
|
||||||
-webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
|
|
||||||
transition: height .4s ease-in-out, top .4s ease-in-out;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .axis {
|
|
||||||
/*
|
|
||||||
-webkit-transition: top .4s ease-in-out;
|
|
||||||
transition: top .4s ease-in-out;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: get animation working nicely
|
|
||||||
|
|
||||||
.vis.timeline .item {
|
|
||||||
-webkit-transition: top .4s ease-in-out;
|
|
||||||
transition: top .4s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .item.line {
|
|
||||||
-webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
|
|
||||||
transition: height .4s ease-in-out, top .4s ease-in-out;
|
|
||||||
}
|
|
||||||
/**/
|
|
||||||
|
|
||||||
.vis.timeline .vispanel.background.horizontal .grid.horizontal {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 0;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel.background.horizontal .grid.minor {
|
|
||||||
border-color: #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .vispanel.background.horizontal .grid.major {
|
|
||||||
border-color: #bfbfbf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.major {
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
color: #4d4d4d;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.major.measure{
|
|
||||||
padding: 0px 0px 0px 0px;
|
|
||||||
margin: 0px 0px 0px 0px;
|
|
||||||
border: 0px;
|
|
||||||
visibility: hidden;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.minor{
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
color: #bebebe;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.minor.measure{
|
|
||||||
padding: 0px 0px 0px 0px;
|
|
||||||
margin: 0px 0px 0px 0px;
|
|
||||||
border: 0px;
|
|
||||||
visibility: hidden;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.title{
|
|
||||||
position: absolute;
|
|
||||||
color: #4d4d4d;
|
|
||||||
white-space: nowrap;
|
|
||||||
bottom: 20px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.title.measure{
|
|
||||||
padding: 0px 0px 0px 0px;
|
|
||||||
margin: 0px 0px 0px 0px;
|
|
||||||
visibility: hidden;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.title.left {
|
|
||||||
bottom: 0px;
|
|
||||||
-webkit-transform-origin: left top;
|
|
||||||
-moz-transform-origin: left top;
|
|
||||||
-ms-transform-origin: left top;
|
|
||||||
-o-transform-origin: left top;
|
|
||||||
transform-origin: left bottom;
|
|
||||||
-webkit-transform: rotate(-90deg);
|
|
||||||
-moz-transform: rotate(-90deg);
|
|
||||||
-ms-transform: rotate(-90deg);
|
|
||||||
-o-transform: rotate(-90deg);
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .dataaxis .yAxis.title.right {
|
|
||||||
bottom: 0px;
|
|
||||||
-webkit-transform-origin: right bottom;
|
|
||||||
-moz-transform-origin: right bottom;
|
|
||||||
-ms-transform-origin: right bottom;
|
|
||||||
-o-transform-origin: right bottom;
|
|
||||||
transform-origin: right bottom;
|
|
||||||
-webkit-transform: rotate(90deg);
|
|
||||||
-moz-transform: rotate(90deg);
|
|
||||||
-ms-transform: rotate(90deg);
|
|
||||||
-o-transform: rotate(90deg);
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .legend {
|
|
||||||
background-color: rgba(247, 252, 255, 0.65);
|
|
||||||
padding: 5px;
|
|
||||||
border-color: #b3b3b3;
|
|
||||||
border-style:solid;
|
|
||||||
border-width: 1px;
|
|
||||||
box-shadow: 2px 2px 10px rgba(154, 154, 154, 0.55);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .legendText {
|
|
||||||
/*font-size: 10px;*/
|
|
||||||
white-space: nowrap;
|
|
||||||
display: inline-block
|
|
||||||
}
|
|
||||||
.vis.timeline .graphGroup0 {
|
|
||||||
fill:#4f81bd;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #4f81bd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup1 {
|
|
||||||
fill:#f79646;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #f79646;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup2 {
|
|
||||||
fill: #8c51cf;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #8c51cf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup3 {
|
|
||||||
fill: #75c841;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #75c841;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup4 {
|
|
||||||
fill: #ff0100;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #ff0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup5 {
|
|
||||||
fill: #37d8e6;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #37d8e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup6 {
|
|
||||||
fill: #042662;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #042662;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup7 {
|
|
||||||
fill:#00ff26;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #00ff26;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup8 {
|
|
||||||
fill:#ff00ff;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #ff00ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .graphGroup9 {
|
|
||||||
fill: #8f3938;
|
|
||||||
fill-opacity:0;
|
|
||||||
stroke-width:2px;
|
|
||||||
stroke: #8f3938;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .fill {
|
|
||||||
fill-opacity:0.1;
|
|
||||||
stroke: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .bar {
|
|
||||||
fill-opacity:0.5;
|
|
||||||
stroke-width:1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .point {
|
|
||||||
stroke-width:2px;
|
|
||||||
fill-opacity:1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .legendBackground {
|
|
||||||
stroke-width:1px;
|
|
||||||
fill-opacity:0.9;
|
|
||||||
fill: #ffffff;
|
|
||||||
stroke: #c2c2c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vis.timeline .outline {
|
|
||||||
stroke-width:1px;
|
|
||||||
fill-opacity:1;
|
|
||||||
fill: #ffffff;
|
|
||||||
stroke: #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vis.timeline .iconFill {
|
|
||||||
fill-opacity:0.3;
|
|
||||||
stroke: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
div.network-manipulationDiv {
|
|
||||||
border-width: 0;
|
|
||||||
border-bottom: 1px;
|
|
||||||
border-style:solid;
|
|
||||||
border-color: #d6d9d8;
|
|
||||||
background: #ffffff; /* Old browsers */
|
|
||||||
background: -moz-linear-gradient(top, #ffffff 0%, #fcfcfc 48%, #fafafa 50%, #fcfcfc 100%); /* FF3.6+ */
|
|
||||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(48%,#fcfcfc), color-stop(50%,#fafafa), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */
|
|
||||||
background: -webkit-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */
|
|
||||||
background: -o-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* Opera 11.10+ */
|
|
||||||
background: -ms-linear-gradient(top, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* IE10+ */
|
|
||||||
background: linear-gradient(to bottom, #ffffff 0%,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%); /* W3C */
|
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulation-editMode {
|
|
||||||
position:absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 15px;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulation-closeDiv {
|
|
||||||
position:absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
|
|
||||||
background-position: 20px 3px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-image: url("img/network/cross.png");
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulation-closeDiv:hover {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI {
|
|
||||||
position:relative;
|
|
||||||
top:-7px;
|
|
||||||
font-family: verdana;
|
|
||||||
font-size: 12px;
|
|
||||||
-moz-border-radius: 15px;
|
|
||||||
border-radius: 15px;
|
|
||||||
display:inline-block;
|
|
||||||
background-position: 0px 0px;
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
height:24px;
|
|
||||||
margin: 0px 0px 0px 10px;
|
|
||||||
vertical-align:middle;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0px 8px 0px 8px;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI:hover {
|
|
||||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.20);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI:active {
|
|
||||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.50);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.back {
|
|
||||||
background-image: url("img/network/backIcon.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.none:hover {
|
|
||||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0);
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
div.network-manipulationUI.none:active {
|
|
||||||
box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0);
|
|
||||||
}
|
|
||||||
div.network-manipulationUI.none {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
div.network-manipulationUI.notification{
|
|
||||||
margin: 2px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.add {
|
|
||||||
background-image: url("img/network/addNodeIcon.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.edit {
|
|
||||||
background-image: url("img/network/editIcon.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.edit.editmode {
|
|
||||||
background-color: #fcfcfc;
|
|
||||||
border-style:solid;
|
|
||||||
border-width:1px;
|
|
||||||
border-color: #cccccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.connect {
|
|
||||||
background-image: url("img/network/connectIcon.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-manipulationUI.delete {
|
|
||||||
background-image: url("img/network/deleteIcon.png");
|
|
||||||
}
|
|
||||||
/* top right bottom left */
|
|
||||||
div.network-manipulationLabel {
|
|
||||||
margin: 0px 0px 0px 23px;
|
|
||||||
line-height: 25px;
|
|
||||||
}
|
|
||||||
div.network-seperatorLine {
|
|
||||||
display:inline-block;
|
|
||||||
width:1px;
|
|
||||||
height:20px;
|
|
||||||
background-color: #bdbdbd;
|
|
||||||
margin: 5px 7px 0px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-navigation_wrapper {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
div.network-navigation {
|
|
||||||
width:34px;
|
|
||||||
height:34px;
|
|
||||||
-moz-border-radius: 17px;
|
|
||||||
border-radius: 17px;
|
|
||||||
position:absolute;
|
|
||||||
display:inline-block;
|
|
||||||
background-position: 2px 2px;
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-navigation:hover {
|
|
||||||
box-shadow: 0px 0px 3px 3px rgba(56, 207, 21, 0.30);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-navigation:active {
|
|
||||||
box-shadow: 0px 0px 1px 3px rgba(56, 207, 21, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.network-navigation.up {
|
|
||||||
background-image: url("img/network/upArrow.png");
|
|
||||||
bottom:50px;
|
|
||||||
left:55px;
|
|
||||||
}
|
|
||||||
div.network-navigation.down {
|
|
||||||
background-image: url("img/network/downArrow.png");
|
|
||||||
bottom:10px;
|
|
||||||
left:55px;
|
|
||||||
}
|
|
||||||
div.network-navigation.left {
|
|
||||||
background-image: url("img/network/leftArrow.png");
|
|
||||||
bottom:10px;
|
|
||||||
left:15px;
|
|
||||||
}
|
|
||||||
div.network-navigation.right {
|
|
||||||
background-image: url("img/network/rightArrow.png");
|
|
||||||
bottom:10px;
|
|
||||||
left:95px;
|
|
||||||
}
|
|
||||||
div.network-navigation.zoomIn {
|
|
||||||
background-image: url("img/network/plus.png");
|
|
||||||
bottom:10px;
|
|
||||||
right:15px;
|
|
||||||
}
|
|
||||||
div.network-navigation.zoomOut {
|
|
||||||
background-image: url("img/network/minus.png");
|
|
||||||
bottom:10px;
|
|
||||||
right:55px;
|
|
||||||
}
|
|
||||||
div.network-navigation.zoomExtends {
|
|
||||||
background-image: url("img/network/zoomExtends.png");
|
|
||||||
bottom:50px;
|
|
||||||
right:15px;
|
|
||||||
}
|
|
||||||
div.network-tooltip {
|
|
||||||
position: absolute;
|
|
||||||
visibility: hidden;
|
|
||||||
padding: 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
-moz-border-radius: 3px;
|
|
||||||
-webkit-border-radius: 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid;
|
|
||||||
|
|
||||||
box-shadow: 3px 3px 10px rgba(128, 128, 128, 0.5);
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -17,7 +17,6 @@
|
||||||
<script type="text/javascript" src="./js/jquery.dataTables.min.js"></script>
|
<script type="text/javascript" src="./js/jquery.dataTables.min.js"></script>
|
||||||
|
|
||||||
<!-- css -->
|
<!-- css -->
|
||||||
<link type="text/css" href="./css/vis.min.css" rel="stylesheet"/>
|
|
||||||
<link type="text/css" href="./css/monkeys-admin.css" rel="stylesheet"/>
|
<link type="text/css" href="./css/monkeys-admin.css" rel="stylesheet"/>
|
||||||
<link type="text/css" href="./css/typeahead.css" rel="stylesheet"/>
|
<link type="text/css" href="./css/typeahead.css" rel="stylesheet"/>
|
||||||
<link type="text/css" href="./css/bootstrap.min.css" rel="stylesheet"/>
|
<link type="text/css" href="./css/bootstrap.min.css" rel="stylesheet"/>
|
||||||
|
@ -68,14 +67,24 @@
|
||||||
<a href="#options" data-toggle="collapse">Options</a>
|
<a href="#options" data-toggle="collapse">Options</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="options" class="panel-body panel-collapse collapse in">
|
<div id="options" class="panel-body panel-collapse collapse in">
|
||||||
<button id="btnCreateJob" class="btn btn-default" type="button"
|
<span class="input-group-btn">
|
||||||
onclick="createNewJob()" style="margin-top:-4px">
|
<button id="btnCreateJob" class="btn btn-default" type="button"
|
||||||
Create new scenario
|
onclick="createNewJob()" style="margin-top:-4px">
|
||||||
</button>
|
Create new scenario
|
||||||
|
</button>
|
||||||
|
<button id="btnConfigSched" class="btn btn-default" type="button"
|
||||||
|
onclick="configSched()" style="margin-top:-4px">
|
||||||
|
Configure Auto Tester
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
<!-- General options -->
|
<!-- General options -->
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<a href="#general" data-toggle="collapse">General</a>
|
<a href="#newJob" data-toggle="collapse">New Job</a>
|
||||||
|
</div>
|
||||||
|
<div id="newJob" style="overflow: visible" class="panel-body panel-collapse collapse in" aria-expanded="true">
|
||||||
|
<div id="job-config">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.General options -->
|
<!-- /.General options -->
|
||||||
|
@ -115,8 +124,7 @@
|
||||||
Update
|
Update
|
||||||
</button>-->
|
</button>-->
|
||||||
</span>
|
</span>
|
||||||
<div style="display: none;" id="job-config">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -96,26 +96,6 @@ function initAdmin() {
|
||||||
startval: $,
|
startval: $,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
jobCfg = new JSONEditor(document.getElementById('job-config'),{
|
|
||||||
schema: {
|
|
||||||
type: "object",
|
|
||||||
title: "Job",
|
|
||||||
properties: {
|
|
||||||
vlan: {
|
|
||||||
title: "Vlan",
|
|
||||||
type: "integer",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
"collapsed": true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
disable_edit_json: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
window.setTimeout(updateJobs, 10000);
|
window.setTimeout(updateJobs, 10000);
|
||||||
loadVcenterConfig();
|
loadVcenterConfig();
|
||||||
updateJobs();
|
updateJobs();
|
||||||
|
@ -141,14 +121,14 @@ function updateJobs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadVcenterConfig() {
|
function loadVcenterConfig() {
|
||||||
$.getJSON('/connector?type=vcenter', function(json) {
|
$.getJSON('/connector?type=VCenterConnector', function(json) {
|
||||||
vcenterCfg.setValue(json);
|
vcenterCfg.setValue(json);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVcenterConfig() {
|
function updateVcenterConfig() {
|
||||||
var vc_config = vcenterCfg.getValue()
|
var vc_config = vcenterCfg.getValue()
|
||||||
vc_config["type"] = "vcenter";
|
vc_config["type"] = "VCenterConnector";
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
headers : {
|
headers : {
|
||||||
|
@ -173,6 +153,30 @@ function updateVcenterConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createNewJob() {
|
function createNewJob() {
|
||||||
|
elem = document.getElementById('job-config');
|
||||||
|
elem.innerHTML = ""
|
||||||
|
jobCfg = new JSONEditor(elem,{
|
||||||
|
schema: {
|
||||||
|
type: "object",
|
||||||
|
title: "Job",
|
||||||
|
properties: {
|
||||||
|
job: {
|
||||||
|
title: "Type",
|
||||||
|
$ref: "/jobcreate",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
"collapsed": false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ajax: true,
|
||||||
|
disable_edit_json: false,
|
||||||
|
disable_collapse: true,
|
||||||
|
disable_properties: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function configSched() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
class NetControllerConnector(object):
|
class NetControllerConnector(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
_properties = {}
|
self._properties = {}
|
||||||
|
|
||||||
def _load_prop_dict(self, target, prop):
|
def _load_prop_dict(self, target, prop):
|
||||||
for property in prop:
|
for property in prop:
|
||||||
|
@ -12,6 +12,9 @@ class NetControllerConnector(object):
|
||||||
else:
|
else:
|
||||||
target[property] = prop[property]
|
target[property] = prop[property]
|
||||||
|
|
||||||
|
def is_connected(self):
|
||||||
|
return False
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -33,3 +36,19 @@ class NetControllerConnector(object):
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
class NetControllerJob(object):
|
||||||
|
connector = NetControllerConnector
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._properties = {
|
||||||
|
# property: [value, enumerating_function]
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_job_properties(self):
|
||||||
|
return self._properties
|
||||||
|
|
||||||
|
def set_job_properties(self, properties):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
raise NotImplementedError()
|
|
@ -0,0 +1,43 @@
|
||||||
|
from connectors import NetControllerJob, NetControllerConnector
|
||||||
|
|
||||||
|
demo_state = {
|
||||||
|
501: ["Machine A", "Machine B"],
|
||||||
|
502: ["Machine C",],
|
||||||
|
503: ["Machine D",],
|
||||||
|
514: ["Machine E", "Machine F"],
|
||||||
|
}
|
||||||
|
|
||||||
|
class DemoConnector(NetControllerConnector):
|
||||||
|
def __init__(self):
|
||||||
|
self._conn = None
|
||||||
|
self._properties = {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"port": 0,
|
||||||
|
"username": "",
|
||||||
|
"password": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self._conn = object()
|
||||||
|
|
||||||
|
def is_connected(self):
|
||||||
|
return not self._conn == None
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
self._conn = None
|
||||||
|
|
||||||
|
def get_vlans_list(self):
|
||||||
|
return demo_state.keys()
|
||||||
|
|
||||||
|
def get_entities_on_vlan(self, vlanid):
|
||||||
|
if (demo_state.has_key(vlanid)):
|
||||||
|
return demo_state[vlanid]
|
||||||
|
return []
|
||||||
|
|
||||||
|
class DemoJob(NetControllerJob):
|
||||||
|
connector = DemoConnector
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._properties = {
|
||||||
|
"vlan": [0, "get_vlans_list"],
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
from connectors import NetControllerConnector
|
from connectors import NetControllerJob, NetControllerConnector
|
||||||
from pyVmomi import vim
|
from pyVmomi import vim
|
||||||
from pyVim.connect import SmartConnect, Disconnect
|
from pyVim.connect import SmartConnect, Disconnect
|
||||||
|
|
||||||
|
|
||||||
class VCenterConnector(NetControllerConnector):
|
class VCenterConnector(NetControllerConnector):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._service_instance = None
|
self._service_instance = None
|
||||||
|
@ -21,15 +20,45 @@ class VCenterConnector(NetControllerConnector):
|
||||||
"resource_pool": ""
|
"resource_pool": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self._cache = {
|
||||||
|
"vlans" : []
|
||||||
|
}
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
self._service_instance = SmartConnect(host=self._address,
|
import ssl
|
||||||
port=self._port,
|
try:
|
||||||
user=self._username,
|
self._service_instance = SmartConnect(host=self._properties["address"],
|
||||||
pwd=self._password)
|
port=self._properties["port"],
|
||||||
|
user=self._properties["username"],
|
||||||
|
pwd=self._properties["password"])
|
||||||
|
except ssl.SSLError:
|
||||||
|
# some organizations use self-signed certificates...
|
||||||
|
gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
|
self._service_instance = SmartConnect(host=self._properties["address"],
|
||||||
|
port=self._properties["port"],
|
||||||
|
user=self._properties["username"],
|
||||||
|
pwd=self._properties["password"],
|
||||||
|
sslContext=gcontext)
|
||||||
|
|
||||||
|
def is_connected(self):
|
||||||
|
if (self._service_instance == None):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
self._service_instance.serverClock
|
||||||
|
except vim.fault.NotAuthenticated, e:
|
||||||
|
return False
|
||||||
|
|
||||||
def get_vlans_list(self):
|
def get_vlans_list(self):
|
||||||
return []
|
if not self.is_connected():
|
||||||
|
self.connect()
|
||||||
|
if self._cache and self._cache.has_key("vlans") and self._cache["vlans"]:
|
||||||
|
return self._cache["vlans"]
|
||||||
|
vcontent = self._service_instance.RetrieveContent() # get updated vsphare state
|
||||||
|
vimtype = [vim.Network]
|
||||||
|
objview = vcontent.viewManager.CreateContainerView(vcontent.rootFolder, vimtype, True)
|
||||||
|
self._cache["vlans"] = [x.name for x in objview.view]
|
||||||
|
objview.Destroy()
|
||||||
|
return self._cache["vlans"]
|
||||||
|
|
||||||
def get_entities_on_vlan(self, vlanid):
|
def get_entities_on_vlan(self, vlanid):
|
||||||
return []
|
return []
|
||||||
|
@ -121,3 +150,13 @@ class VCenterConnector(NetControllerConnector):
|
||||||
break
|
break
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class VCenterJob(NetControllerJob):
|
||||||
|
connector = VCenterConnector
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._properties = {
|
||||||
|
"vlan": [0, "get_vlans_list"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from flask import Flask, request, abort, send_from_directory
|
from flask import Flask, request, abort, send_from_directory
|
||||||
from flask.ext import restful
|
from flask.ext import restful
|
||||||
from flask.ext.pymongo import PyMongo
|
from flask.ext.pymongo import PyMongo
|
||||||
|
@ -7,7 +8,8 @@ import bson.json_util
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
from connectors.vcenter import VCenterConnector
|
from connectors.vcenter import VCenterJob, VCenterConnector
|
||||||
|
from connectors.demo import DemoJob, DemoConnector
|
||||||
|
|
||||||
MONGO_URL = os.environ.get('MONGO_URL')
|
MONGO_URL = os.environ.get('MONGO_URL')
|
||||||
if not MONGO_URL:
|
if not MONGO_URL:
|
||||||
|
@ -17,6 +19,10 @@ app = Flask(__name__)
|
||||||
app.config['MONGO_URI'] = MONGO_URL
|
app.config['MONGO_URI'] = MONGO_URL
|
||||||
mongo = PyMongo(app)
|
mongo = PyMongo(app)
|
||||||
|
|
||||||
|
available_jobs = [VCenterJob, DemoJob]
|
||||||
|
|
||||||
|
active_connectors = {}
|
||||||
|
|
||||||
class Root(restful.Resource):
|
class Root(restful.Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
return {
|
return {
|
||||||
|
@ -64,9 +70,9 @@ class Job(restful.Resource):
|
||||||
class Connector(restful.Resource):
|
class Connector(restful.Resource):
|
||||||
def get(self, **kw):
|
def get(self, **kw):
|
||||||
type = request.args.get('type')
|
type = request.args.get('type')
|
||||||
if (type == 'vcenter'):
|
if (type == 'VCenterConnector'):
|
||||||
vcenter = VCenterConnector()
|
vcenter = VCenterConnector()
|
||||||
properties = mongo.db.connector.find_one({"type": 'vcenter'})
|
properties = mongo.db.connector.find_one({"type": 'VCenterConnector'})
|
||||||
if properties:
|
if properties:
|
||||||
vcenter.load_properties(properties)
|
vcenter.load_properties(properties)
|
||||||
ret = vcenter.get_properties()
|
ret = vcenter.get_properties()
|
||||||
|
@ -76,17 +82,61 @@ class Connector(restful.Resource):
|
||||||
|
|
||||||
def post(self, **kw):
|
def post(self, **kw):
|
||||||
settings_json = json.loads(request.data)
|
settings_json = json.loads(request.data)
|
||||||
if (settings_json.get("type") == 'vcenter'):
|
if (settings_json.get("type") == 'VCenterConnector'):
|
||||||
|
|
||||||
# preserve password
|
# preserve password
|
||||||
properties = mongo.db.connector.find_one({"type": 'vcenter'})
|
properties = mongo.db.connector.find_one({"type": 'VCenterConnector'})
|
||||||
if properties and (not settings_json.has_key("password") or not settings_json["password"]):
|
if properties and (not settings_json.has_key("password") or not settings_json["password"]):
|
||||||
settings_json["password"] = properties.get("password")
|
settings_json["password"] = properties.get("password")
|
||||||
|
|
||||||
return mongo.db.connector.update({"type": 'vcenter'},
|
return mongo.db.connector.update({"type": 'VCenterConnector'},
|
||||||
{"$set": settings_json},
|
{"$set": settings_json},
|
||||||
upsert=True)
|
upsert=True)
|
||||||
|
|
||||||
|
class JobCreation(restful.Resource):
|
||||||
|
def get(self, **kw):
|
||||||
|
jobtype = request.args.get('type')
|
||||||
|
if not jobtype:
|
||||||
|
res = []
|
||||||
|
update_connectors()
|
||||||
|
for con in available_jobs:
|
||||||
|
if con.connector.__name__ in active_connectors:
|
||||||
|
res.append({"title": con.__name__, "$ref": "/jobcreate?type=" + con.__name__})
|
||||||
|
return {"oneOf": res}
|
||||||
|
|
||||||
|
job = None
|
||||||
|
for jobclass in available_jobs:
|
||||||
|
if jobclass.__name__ == jobtype:
|
||||||
|
job = jobclass()
|
||||||
|
|
||||||
|
if job and job.connector.__name__ in active_connectors.keys():
|
||||||
|
properties = dict()
|
||||||
|
job_prop = job.get_job_properties()
|
||||||
|
|
||||||
|
for prop in job_prop:
|
||||||
|
properties[prop] = dict({})
|
||||||
|
if type(job_prop[prop][0]) is int:
|
||||||
|
properties[prop]["type"] = "number"
|
||||||
|
elif type(job_prop[prop][0]) is bool:
|
||||||
|
properties[prop]["type"] = "boolean"
|
||||||
|
else:
|
||||||
|
properties[prop]["type"] = "string"
|
||||||
|
if job_prop[prop][1]:
|
||||||
|
properties[prop]["enum"] = list(active_connectors[job.connector.__name__].__getattribute__(job_prop[prop][1])())
|
||||||
|
|
||||||
|
res = dict({
|
||||||
|
"title": "%s Job" % jobtype,
|
||||||
|
"type": "object",
|
||||||
|
"options": {
|
||||||
|
"disable_collapse": True,
|
||||||
|
"disable_properties": True,
|
||||||
|
},
|
||||||
|
"properties": properties
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def normalize_obj(obj):
|
def normalize_obj(obj):
|
||||||
if obj.has_key('_id') and not obj.has_key('id'):
|
if obj.has_key('_id') and not obj.has_key('id'):
|
||||||
|
@ -113,6 +163,30 @@ def output_json(obj, code, headers=None):
|
||||||
resp.headers.extend(headers or {})
|
resp.headers.extend(headers or {})
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
def refresh_connector_config(name):
|
||||||
|
properties = mongo.db.connector.find_one({"type": name})
|
||||||
|
if properties:
|
||||||
|
active_connectors[name].load_properties(properties)
|
||||||
|
|
||||||
|
|
||||||
|
def update_connectors():
|
||||||
|
for con in available_jobs:
|
||||||
|
connector_name = con.connector.__name__
|
||||||
|
if connector_name not in active_connectors:
|
||||||
|
active_connectors[connector_name] = con.connector()
|
||||||
|
|
||||||
|
if not active_connectors[connector_name].is_connected():
|
||||||
|
refresh_connector_config(connector_name)
|
||||||
|
try:
|
||||||
|
app.logger.info("Trying to activate connector: %s" % connector_name)
|
||||||
|
active_connectors[connector_name].connect()
|
||||||
|
except Exception, e:
|
||||||
|
active_connectors.pop(connector_name)
|
||||||
|
app.logger.info("Error activating connector: %s, reason: %s" % (connector_name, e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/admin/<path:path>')
|
@app.route('/admin/<path:path>')
|
||||||
def send_admin(path):
|
def send_admin(path):
|
||||||
return send_from_directory('admin/ui', path)
|
return send_from_directory('admin/ui', path)
|
||||||
|
@ -124,6 +198,7 @@ api.representations = DEFAULT_REPRESENTATIONS
|
||||||
api.add_resource(Root, '/api')
|
api.add_resource(Root, '/api')
|
||||||
api.add_resource(Job, '/job')
|
api.add_resource(Job, '/job')
|
||||||
api.add_resource(Connector, '/connector')
|
api.add_resource(Connector, '/connector')
|
||||||
|
api.add_resource(JobCreation, '/jobcreate')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key'))
|
app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key'))
|
||||||
|
|
Loading…
Reference in New Issue