+
+ {{ config.message.title }}
+
+ {{ config.message.content }}
+
+ diff --git a/README.md b/README.md index c98564a..12a2940 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,81 @@ -# homer -A very simple static homepage for your server. +# Homer +A very simple static HOMepage for your servER. +Add all your useful service, external links, notes... or anything. + +If you need authentication support, you're on your own (it can be secured using a web server auth module or exposing it only through a VPN network / SSH tunneling, ...) + + + +**How to build / install it? Where is the webpack config?** +There is no build system (😱), use it like that! It'meant to be stupid simple & zero maintenance required. just copy the static files somewhere, and visit the `index.html`. + + +## configuration + +Title, icons, links, colors, and services can be configured in the `config.yml` file, using [yaml](http://yaml.org/) format. + + +```yaml +--- +# Homepage configuration +# See https://fontawesome.com/v4.7.0/icons/ for icons options + +title: "Simple homepage" +subtitle: "Homer" +logo: "assets/homer.png" + +# Optional message +message: + title: "Optional message!" + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque risus mi, tempus quis placerat ut, porta nec nulla. Vestibulum rhoncus ac ex sit amet fringilla. Nullam gravida purus diam, et dictum felis venenatis efficitur. Aenean ac eleifend lacus, in mollis lectus. Donec sodales, arcu et sollicitudin porttitor, tortor urna tempor ligula." + +# Optional navbar +links: + - name: "ansible" + icon: "fa-github" + url: "https://github.com/xxxxx/ansible/" + - name: "Wiki" + icon: "fa-book" + url: "https://wiki.xxxxxx.com/" + +# Services +# First level array represent a group. +# Leave only a "items" key if not using group (group name & icon are optional, section separation will not be displayed). +services: + - name: "DevOps" + icon: "fa-code-fork" + items: + - name: "Jenkins" + logo: "/assets/tools/jenkins.png" + subtitle: "Continuous integration server" + tag: "CI" + url: "#" + - name: "RabbitMQ Management" + logo: "/assets/tools/rabbitmq.png" + subtitle: "Manage & monitor RabbitMQ server" + tag: "haproxy" + url: "#" + - name: "Monitoring" + icon: "fa-heartbeat" + items: + - name: "M/Monit" + logo: "/assets/tools/monit.png" + subtitle: "Monitor & manage all monit enabled hosts" + tag: "monit" + url: "#" + - name: "Grafana" + logo: "/assets/tools/grafana.png" + subtitle: "Metric analytics & dashboards" + url: "#" + - name: "Kibana" + logo: "/assets/tools/elastic.png" + subtitle: "Explore & visualize logs" + tag: "elk" + url: "#" + - name: "Website monitoring" + logo: "/assets/tools/pingdom.png" + subtitle: "Pingdom public reports overview" + tag: "CI" + url: "#" + +``` \ No newline at end of file diff --git a/app.css b/app.css new file mode 100644 index 0000000..7a4c255 --- /dev/null +++ b/app.css @@ -0,0 +1,130 @@ +body { + font-family: 'Raleway', sans-serif; + background-color: #F5F5F5; + height: 100%; } + body h1, body h2, body h3, body h4, body h5, body h6 { + font-family: 'Lato', sans-serif; } + body h1 { + font-size: 2rem; } + body h2 { + font-size: 1.7rem; + margin-top: 3rem; + margin-bottom: 1rem; } + body h2 .fa { + margin-right: 10px; + color: #4285f4; } + body h2 span { + font-weight: bold; + color: #4285f4; } + body [v-cloak] { + display: none; } + body #bighead { + color: #ffffff; } + body #bighead .dashboard-title { + padding: 6px 0 0 80px; } + body #bighead .first-line { + height: 100px; + vertical-align: center; + background-color: #3367d6; } + body #bighead .first-line h1 { + margin-top: -12px; + font-size: 2rem; } + body #bighead .first-line .headline { + margin-top: 5px; + font-size: 0.9rem; } + body #bighead .first-line .container { + height: 80px; + padding: 10px 0; } + body #bighead .first-line img { + float: left; + max-height: 70px; + max-width: 70px; + padding: 10px; } + body #bighead .navbar { + background-color: #4285f4; } + body #bighead .navbar a { + color: #152138; } + body #bighead .navbar a:hover { + background-color: #5a95f5; } + body #main-section { + margin-bottom: 3rem; + padding: 0; } + body #main-section h2 { + border-bottom: 1px dashed #ccc; + padding-bottom: 10px; } + body #main-section .title { + font-size: 1.1em; } + body #main-section .subtitle { + font-size: .9em; } + body #main-section .column { + padding: 1.2rem .75rem; } + body #main-section .message { + margin-top: 45px; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } + body #main-section .message .message-header { + font-weight: bold; } + body #main-section .message .message-body { + border: none; } + body .media-content { + overflow: inherit; } + body .tag { + color: #4285f4; + background-color: #4285f4; + position: absolute; + top: 1rem; + right: -0.3rem; + width: 3px; + overflow: hidden; + transition: all 0.2s ease-out; + padding: 0; } + body .card { + border-radius: 5px; + border: none; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); + transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; } + body .card:hover { + background-color: #FFFFFF; + transform: translate(0, -3px); } + body .card:hover .tag { + width: auto; + color: #ffffff; + padding: 0 0.75em; } + body .card-content { + height: 110px; } + body .footer { + position: fixed; + left: 0; + right: 0; + bottom: 0; + padding: 1rem 0.5rem; + text-align: left; + background-color: #fafafa; + border-top: 1px solid #F5F5F5; } + body .search-bar { + position: relative; } + body .search-bar #search { + border: none; + background-color: #5f98f6; + border-radius: 5px; + padding: 2px 12px 2px 30px; + margin: 10px 0; + transition: all 100ms linear; + color: #ffffff; + height: 30px; + width: 100px; } + body .search-bar #search:focus { + color: #000000; + width: 250px; + background-color: #ffffff; } + body .search-bar .search-label::before { + font-family: 'FontAwesome'; + position: absolute; + top: 12px; + left: 8px; + content: "\f002"; + width: 20px; + height: 20px; } + body .search-bar:focus-within .search-label::before { + color: #4a4a4a; } + +/*# sourceMappingURL=app.css.map */ diff --git a/app.css.map b/app.css.map new file mode 100644 index 0000000..9e5dc0c --- /dev/null +++ b/app.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "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", +"sources": ["app.scss"], +"names": [], +"file": "app.css" +} \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..2697975 --- /dev/null +++ b/app.js @@ -0,0 +1,58 @@ +var app = new Vue({ + el: '#app', + data: { + config: null, + filter: '' + }, + beforeCreate () { + var that = this; + return getConfig().then(function (config) { + // Splice services list into groups of 3 for flex column display + var size = 3; + config.services.forEach(function(service) { + service.rows = []; + items = service.items; + while (items.length) { + service.rows.push(items.splice(0, size)); + } + + if (service.rows.length) { + var last = service.rows.length-1; + service.rows[last] = service.rows[last].concat(Array(size - service.rows[last].length)); + } + }); + that.config = config; + }); + } +}); + + +function getConfig() { + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'config.yml'); + xhr.onload = function () { + if (this.status >= 200 && this.status < 300) { + try { + var data = jsyaml.load(xhr.response); + resolve(data); + } catch (e) { + console.error('fail to parse config file'); + reject(); + } + } else { + reject({ + status: this.status, + statusText: xhr.statusText + }); + } + }; + xhr.onerror = function () { + reject({ + status: this.status, + statusText: xhr.statusText + }); + }; + xhr.send(); + }); +} \ No newline at end of file diff --git a/app.scss b/app.scss new file mode 100644 index 0000000..6391c2d --- /dev/null +++ b/app.scss @@ -0,0 +1,204 @@ +$primary-color: #3367d6; +$secondary-color: #4285f4; + +body { + font-family: 'Raleway', sans-serif; + background-color: #F5F5F5; + height: 100%; + + h1, h2, h3, h4, h5, h6 { + font-family: 'Lato', sans-serif; + } + + h1 { + font-size: 2rem; + } + + h2 { + font-size: 1.7rem; + margin-top: 3rem; + margin-bottom: 1rem; + + .fa { + margin-right: 10px; + color: $secondary-color; + } + + span { + font-weight: bold; + color: $secondary-color; + } + } + + [v-cloak] { + display: none + } + + #bighead { + color: #ffffff; + + .dashboard-title { + padding: 6px 0 0 80px; + } + + .first-line { + height: 100px; + vertical-align: center; + background-color: $primary-color; + + h1 { + margin-top: -12px; + font-size: 2rem; + } + + .headline { + margin-top: 5px; + font-size: 0.9rem; + } + + .container { + height: 80px; + padding: 10px 0; + } + + img { + float: left; + max-height: 70px; + max-width: 70px; + padding: 10px; + } + } + .navbar { + background-color: $secondary-color; + + a { + color: #152138; + + &:hover { + background-color: lighten( $secondary-color, 5% ); + } + } + } + } + + #main-section { + margin-bottom: 3rem; + padding: 0; + + h2 { + border-bottom: 1px dashed #ccc; + padding-bottom: 10px; + } + + .title { + font-size: 1.1em; + } + + .subtitle { + font-size: .9em; + } + + .column { + padding: 1.2rem .75rem; + } + + .message { + margin-top: 45px; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); + + .message-header { + font-weight: bold; + } + + .message-body { + border: none; + } + } + } + + .media-content { + overflow: inherit; + } + + .tag { + color: $secondary-color; + background-color: $secondary-color; + position: absolute; + top: 1rem; + right: -0.3rem; + width: 3px; + overflow: hidden; + transition: all 0.2s ease-out; + padding: 0; + } + + .card { + border-radius: 5px; + border: none; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); + transition: cubic-bezier(0.165, 0.84, 0.44, 1) 300ms + } + + .card:hover { + background-color: #FFFFFF; + transform: translate(0, -3px); + + .tag { + width: auto; + color: #ffffff; + padding: 0 0.75em; + } + } + + .card-content { + height: 110px; + } + + .footer { + position: fixed; + left: 0; + right: 0; + bottom: 0; + padding: 1rem 0.5rem; + text-align: left; + background-color: #fafafa; + border-top: 1px solid #F5F5F5; + } + + .search-bar { + position: relative; + #search { + border: none; + background-color: lighten( $secondary-color, 6% ); + border-radius: 5px; + padding: 2px 12px 2px 30px; + margin: 10px 0; + transition: all 100ms linear; + color: #ffffff; + height: 30px; + width: 100px; + + + &:focus { + color: #000000; + width: 250px; + background-color: #ffffff; + } + } + + .search-label::before { + font-family: 'FontAwesome'; + position: absolute; + top: 12px; + left: 8px; + content: "\f002"; + width: 20px; + height: 20px; + } + + &:focus-within .search-label::before { + color: #4a4a4a; + } + } + +} diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 0000000..6fa8ee8 Binary files /dev/null and b/assets/favicon.png differ diff --git a/assets/homer.png b/assets/homer.png new file mode 100644 index 0000000..6fa8ee8 Binary files /dev/null and b/assets/homer.png differ diff --git a/assets/tools/elastic.png b/assets/tools/elastic.png new file mode 100644 index 0000000..11d655f Binary files /dev/null and b/assets/tools/elastic.png differ diff --git a/assets/tools/grafana.png b/assets/tools/grafana.png new file mode 100644 index 0000000..65de946 Binary files /dev/null and b/assets/tools/grafana.png differ diff --git a/assets/tools/jenkins.png b/assets/tools/jenkins.png new file mode 100644 index 0000000..6afeb65 Binary files /dev/null and b/assets/tools/jenkins.png differ diff --git a/assets/tools/kibana.png b/assets/tools/kibana.png new file mode 100644 index 0000000..c38b32b Binary files /dev/null and b/assets/tools/kibana.png differ diff --git a/assets/tools/monit.png b/assets/tools/monit.png new file mode 100644 index 0000000..1aa8c95 Binary files /dev/null and b/assets/tools/monit.png differ diff --git a/assets/tools/pingdom.png b/assets/tools/pingdom.png new file mode 100644 index 0000000..ec290ed Binary files /dev/null and b/assets/tools/pingdom.png differ diff --git a/assets/tools/rabbitmq.png b/assets/tools/rabbitmq.png new file mode 100644 index 0000000..90e2178 Binary files /dev/null and b/assets/tools/rabbitmq.png differ diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..09dd14e --- /dev/null +++ b/config.yml @@ -0,0 +1,63 @@ +--- +# Homepage configuration +# See https://fontawesome.com/v4.7.0/icons/ for icons options + +title: "Simple homepage" +subtitle: "Homer" +logo: "assets/homer.png" + +# Optional message +# See https://bulma.io/documentation/components/message/#colors for styling options. +message: + style: "is-warning" + title: "Optional message!" + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque risus mi, tempus quis placerat ut, porta nec nulla. Vestibulum rhoncus ac ex sit amet fringilla. Nullam gravida purus diam, et dictum felis venenatis efficitur. Aenean ac eleifend lacus, in mollis lectus. Donec sodales, arcu et sollicitudin porttitor, tortor urna tempor ligula." + +# Optional navbar +links: + - name: "ansible" + icon: "fa-github" + url: "https://github.com/xxxxx/ansible/" + - name: "Wiki" + icon: "fa-book" + url: "https://wiki.xxxxxx.com/" + +# Services +# First level array represent a group. +# Leave only a "items" key if not using group (group name & icon are optional, section separation will not be displayed). +services: + - name: "DevOps" + icon: "fa-code-fork" + items: + - name: "Jenkins" + logo: "/assets/tools/jenkins.png" + subtitle: "Continuous integration server" + tag: "CI" + url: "#" + - name: "RabbitMQ Management" + logo: "/assets/tools/rabbitmq.png" + subtitle: "Manage & monitor RabbitMQ server" + tag: "haproxy" + url: "#" + - name: "Monitoring" + icon: "fa-heartbeat" + items: + - name: "M/Monit" + logo: "/assets/tools/monit.png" + subtitle: "Monitor & manage all monit enabled hosts" + tag: "monit" + url: "#" + - name: "Grafana" + logo: "/assets/tools/grafana.png" + subtitle: "Metric analytics & dashboards" + url: "#" + - name: "Kibana" + logo: "/assets/tools/elastic.png" + subtitle: "Explore & visualize logs" + tag: "elk" + url: "#" + - name: "Website monitoring" + logo: "/assets/tools/pingdom.png" + subtitle: "Pingdom public reports overview" + tag: "CI" + url: "#" diff --git a/index.html b/index.html new file mode 100644 index 0000000..9e946bf --- /dev/null +++ b/index.html @@ -0,0 +1,107 @@ + + +
+ + + + +