voxpupuli / puppetboard Goto Github PK
View Code? Open in Web Editor NEWWeb frontend for PuppetDB
Home Page: https://pypi.org/project/puppetboard/
License: Apache License 2.0
Web frontend for PuppetDB
Home Page: https://pypi.org/project/puppetboard/
License: Apache License 2.0
I have a weird bug that my node throws an error but it doesnt show up on the dashboard.
root@ci-resloc-03:~# puppet agent -t
Info: Retrieving plugin
Info: Loading facts in /etc/puppet/lib/facter/facter_dot_d.rb
Info: Loading facts in /etc/puppet/lib/facter/pe_version.rb
Info: Loading facts in /etc/puppet/lib/facter/iptables_persistent_version.rb
Info: Loading facts in /etc/puppet/lib/facter/unix_default_gateway.rb
Info: Loading facts in /etc/puppet/lib/facter/otenvironment.rb
Info: Loading facts in /etc/puppet/lib/facter/python_version.rb
Info: Loading facts in /etc/puppet/lib/facter/root_home.rb
Info: Loading facts in /etc/puppet/lib/facter/environment.rb
Info: Loading facts in /etc/puppet/lib/facter/esx_version.rb
Info: Loading facts in /etc/puppet/lib/facter/rabbitmq_erlang_cookie.rb
Info: Loading facts in /etc/puppet/lib/facter/pper_installed.rb
Info: Loading facts in /etc/puppet/lib/facter/jenkins.rb
Info: Loading facts in /etc/puppet/lib/facter/datacenter.rb
Info: Loading facts in /etc/puppet/lib/facter/iptables_version.rb
Info: Loading facts in /etc/puppet/lib/facter/ip6tables_version.rb
Info: Loading facts in /etc/puppet/lib/facter/os_maj_version.rb
Info: Loading facts in /etc/puppet/lib/facter/vmwaretools_version.rb
Info: Loading facts in /etc/puppet/lib/facter/concat_basedir.rb
Info: Loading facts in /etc/puppet/lib/facter/ipaddress4.rb
Info: Loading facts in /etc/puppet/lib/facter/pip_version.rb
Info: Loading facts in /etc/puppet/lib/facter/puppet_vardir.rb
Info: Loading facts in /etc/puppet/lib/facter/virtualenv_version.rb
Info: Loading facts in /etc/puppet/lib/facter/agent_configuration.rb
Info: Caching catalog for ci-resloc-03.qasql.opentable.com
Info: Applying configuration version '1395079566'
Error: Could not start Service[jmeter-agent-upstart]: Execution of '/sbin/start jmeter-agent-upstart' returned 1:
Error: /Stage[main]/Application_jmeter_agent/Upstart::Job[jmeter-agent-upstart]/Service[jmeter-agent-upstart]/ensure: change from stopped to running failed: Could not start Service[jmeter-agent-upstart]: Execution of '/sbin/start jmeter-agent-upstart' returned 1:
Error: Could not start Service[jmeter-agent-upstart]: Execution of '/sbin/start jmeter-agent-upstart' returned 1:
Error: /Stage[main]/Application_jmeter_agent/Upstart::Job[jmeter-agent-upstart]/Service[jmeter-agent-upstart]/ensure: change from stopped to running failed: Could not start Service[jmeter-agent-upstart]: Execution of '/sbin/start jmeter-agent-upstart' returned 1:
Notice: Finished catalog run in 3.20 seconds
But yet when i look at the board, i see the following
Has this been seen before? I am using puppet agent 3.4.2, puppetmaster 3.4.3 and puppetdb 1.6
Paul
It would be really nice if the status button could show Pending instead of None when there are changes pending. This is really useful when the puppet agents run in noop mode per default.
If the color of the button could also change to something else than grey when this happens it would be really nice.
Our puppetboard users are all in different timezones, but we like to be able to talk to each other about "the report at such and such time". All our servers use UTC, and that's what we usually use when talking to each other, so it would be great if we could configure puppetboard to use UTC in the web UI regardless of the user's browser timezone.
When running puppetboard with Apache and Passenger on Ubuntu 12.04 with Python 2.7.3 the metric route doesn't work.
It seems like there is a problem with the url encoding with the pypuppetdb metric() method, but it works fine running dev.py and with mod_wsgi.
Log output of the failed HTTP call:
[ pid=11081, time=2014-02-03 09:32:19,168 ]: Exception on /metric/com.jolbox.bonecp%253Atype%253DBoneCP [GET] Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "puppetboard/app.py", line 353, in metric metric = puppetdb.metric(metric) File "/usr/local/lib/python2.7/dist-packages/pypuppetdb/api/__init__.py", line 321, in metric return self._query('mbean', path=metric) File "/usr/local/lib/python2.7/dist-packages/pypuppetdb/api/__init__.py", line 267, in _query r.raise_for_status() File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 683, in raise_for_status raise HTTPError(http_error_msg, response=self) HTTPError: 404 Client Error: Not Found
Hey,
Sorting nodes by catalog or report timestamp on the "Nodes" page does not work for some reason. The table keeps getting sorted by Hostname. This is quite an important functionality when it comes to tracking change propagation and rolling updates.
I tried bump-ing the tablesorter version and playing with the date formatting without success.
I am using the latest master and Firefox 31.0. Let me know if you need any additional info.
When there are machines that have more than 9 changes or errors the width given to that column can't contain the red and green labels anymore because they become a few pixels wider.
We need to fix that in such a way that the column will be at least 220px, not fixed to 220px.
I've always been using the Pupper Dashboard in order to get a quick overview of all nodes which have pending changes, since I run all puppet agents with --noop
.
This doesn't seem to be available in Puppetboard. Is it because of what PuppetDB stores, making it impossible to get that information?
Currently, my nodes with pending changes appear with status None
in the Overview and Nodes pages. I would really like them to show up (in orange for instance) with "with status pending". Would that be possible?
The README contains suggestions such as
$ chown www-data:www-data /var/www/puppetboard
and
Make sure this file [wsgi.py] is owned by the user and group the webserver runs as.
Unless I'm missing something this seems like a bad idea. The webserver needs to read wsgi.py, but it does not need to write to it. If there was a bug in puppetboard that allowed an attacker to write to an arbitrary file, they could write new code under /var/www/puppetboard and rewrite wsgi.py to run that code.
I installed the latest version of puppetboard on CentOS 6.4 and Passenger 4.0.41 but was getting errors when I tried to access the web page. After some investigation and a lot of Googling I was able to modify the passenger_wsgi.py to get it working. I thought I would share what I changed in case this helps any one. Please understand I am not good with python. I am sure there is a better way to do this.
Louis
Replaced the line:
logging.basicConfig(filename=/path/to/file/for/logging, level=logging.INFO)
With these lines
logfilename = os.path.join('/var/log', 'puppetboard.log')
logging.basicConfig(filename=logfilename, level=logging.INFO)
Integrate a JavaScript version of dalen/puppet-puppetdbquery, https://gist.githubusercontent.com/dalen/9730100/raw/9e24ea5da019ff128073ce1978699f545ab77cce/puppetdbquery.js
The warning is because the 'flatly' theme for bootswatch includes a google font via a HTTP link. The file in question is the following, the import statement is at the very top.
https://netdna.bootstrapcdn.com/bootswatch/2.3.2/flatly/bootstrap.min.css
I know, this is not an issue with puppetboard itself, but I thought to report it anyway, maybe somebody knows an easy fix! (Not loading the font file is an easy fix, but produces some layout glitches.)
Enhancement Request: Auto Refresh setting and/or Radiator style view
HI,
I have just migrated from the old puppetdashboard to puppetboard. I love the project. Unfortunately, I got told that the last 10 reports was not enough from one of the engineers.
If I sent a PR to update that to a variable would this be supported? Or is 10 the limit of what we can do easily?
Thanks
Paul
Similar in purpose as Dashboard's radiotor we need a view that shows us the amount of nodes checking in, the amount of failing nodes etc etc.
The last thing that's keeping us from turning off Puppet Dashboard and just using PuppetBoard is the extra detail that's provided in the Dashboard display of a report:
Are my guesses at API availability for these correct? We'd like to avoid losing useful info when we put Dashboard out to pasture, so adding any of these would be handy for us. Great work on PuppetBoard by the way! ๐
A new route like:
@app.route('/fact/fact name/fact value')
Returns the list of the nodes matching that fact lookup. Can probably just use the nodes.html template.
I was just asked: how many windows hosts do we actually have, running Puppet?
I had to cut'n'paste to a shell, to count with wc.. :)
I could have built a query and counted with curl+wc..
But puppetboard was so easy to use.. that it would have given me the answer, if only it had give me a counter for the resultset size.. :)
Next release really needs to support pagination, this is getting ridiculous.
Hi
I followed instructions on installing puppetboard by doing pip install puppetboard and Apache + mod_passenger, but i am getting error in puppetboard.errror.log saying missing puppetboard.app
Not sure what i am doing wrong ?
Many thanks.
Within my puppet manifests I have code like so. The actual password is coming from encrypted storage though.
user{'localadmin'
password=>'theplaintextpassword',
provider=>'windows_adsi';
}
The problem of course is that when the above is applied to a system, it gets logged into puppetdb. Then it gets displayed for everyone with access puppetboard to see. The json for the specific event is below.
{
"containment-path" : [ "Stage[main]", "Localauth", "Localauth::User[localadmin]", "User[localadmin]" ],
"new-value" : "theplaintextpassword",
"containing-class" : "Localauth",
"report-receive-time" : "2014-07-02T22:08:31.286Z",
"report" : "1892d84ef0bbbd6d909e572782f360d21598e1eb",
"resource-title" : "localadmin",
"property" : "password",
"file" : "/srv/puppet/environments/win_production/modules/localauth/manifests/user.pp",
"old-value" : "absent",
"run-start-time" : "2014-07-02T22:06:42.286Z",
"line" : 22,
"status" : "success",
"run-end-time" : "2014-07-02T22:08:15.428Z",
"resource-type" : "User",
"timestamp" : "2014-07-02T22:08:02.318Z",
"configuration-version" : "1404338814",
"certname" : "thecomputer.example.org",
"message" : "created password"
},
It sure would be nice to have some way in puppetboard to set some kind of filter on the server if an event has "resource-type" : "User", and "property" : "password", then the old and new values are hidden from the display.
I suspect this would also be useful for other types of resources where a secret would be displayed as part of the new/old value.
Would be awesome to have the feature to access a few things via RSS.
Things that come into my mind:
Optional:
With 1.5 released we should take advantage of pagination.
Facter 2.0 introduced structured facts (compared to only key-value pairs in 1.x). In the 2.0.x series of Facter, no structured facts were provided by default. However, as stated in the Facter 2.1.0 announcement, now partitions
is the first standard structured fact (hash).
Please add support for this in Puppetboard. By support I mean one should think of a way it can be displayed 'nicely', rather than for example:
partitions {"vda1"=>{"uuid"=>"af740304-b2c6-440f-877a-5fb15cf86c39", "size"=>"12578816", "filesystem"=>"ext4"}}
Just got a question to deliver a list for a boss, who wanted to "play with the results" in a spreadsheet.
Found myself missing puppet-dashboard's CSV export feature :)
It would be great, if one could export all lists (complete list of nodenames, and also resultsets under facts) as csv.
It would be really handy if you could filter nodes by environment. In the overview and the nodes view.
Shouldn't it? ;-)
Hi,
I installed puppetboard on a CentOS 6.5 box by following the instructions on https://github.com/nedap/puppetboard/. Although everything seems to work allright, I am experiencing some strange layout issues where text is cut off at the top. (Both in Firefox 29.0 and Internet Explorer 11).
Kind regards
Florian
Erik has release a Javascript version of puppetdbquery, https://www.npmjs.org/package/node-puppetdbquery.
We should use that in the Query tab to allow people to easily write complex queries.
When a user goes to the nodes page, they need to type the search term in the search bar. When a page refresh happens, it doesnt respect that there is a term in it and it clears the search term
Do you think a query string param would help here?
e.g. /nodes?term=x
Thoughts?
There is a good bit of very useful information that the statusbar in the web UI could report:
Last Refreshed Jun 13, 9:01AM
sorry for the nob question but when I install via pip or the puppet forge module with the "latest" param set, I end up with a very old version of puppetboard. I can tell because many part of the UI are broken and in the bottom right of the screen I see 2013 not 2013-2014.
I'm installing on Centos 6.6/python is 2.6
Any suggestions on what to look at, what I might be doing wrong?
Thanks for the great work on this tool by the way !
first i wanted just to make a simple proxy that connects to each of my puppetdb (per-datacenter) and merges resulting json, then passing it to puppetboard.
but i've noticed that ie. pagination is supported on puppetdb level, so it won't work (we'd receive multiples of results, with likely issues on sorting).
so, are there any plans to make single puppetboard to query multiple puppetdbs?
or maybe select a backend that we want to talk to from a predefined list with some pull-down?
or should i look for anything else?
I have 1200 nodes in puppetdb. Going to the nodes page ends up failing to get all the nodes with:
INFO:werkzeug:17.153.45.123 - - [21/Aug/2013 21:38:25] "GET /nodes HTTP/1.1" 200 -
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): seovm57.apple.com
Debugging middleware caught exception in streamed response at a point where response headers were already sent.
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/werkzeug/wsgi.py", line 682, in next
return self._next()
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 81, in _iter_encoded
for item in iterable:
File "/Library/Python/2.7/site-packages/flask/helpers.py", line 122, in generator
for item in gen:
File "/Library/Python/2.7/site-packages/Jinja2-2.7-py2.7.egg/jinja2/environment.py", line 1186, in next
return self._next()
File "/Library/Python/2.7/site-packages/Jinja2-2.7-py2.7.egg/jinja2/environment.py", line 1168, in generator
c = next()
File "/Library/Python/2.7/site-packages/Jinja2-2.7-py2.7.egg/jinja2/environment.py", line 993, in generate
yield self.environment.handle_exception(exc_info, True)
File "/Library/Python/2.7/site-packages/Jinja2-2.7-py2.7.egg/jinja2/environment.py", line 742, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/blysik/Documents/git/puppetboard/puppetboard/templates/nodes.html", line 1, in top-level template code
{% extends 'layout.html' %}
File "/Users/blysik/Documents/git/puppetboard/puppetboard/templates/layout.html", line 39, in top-level template code
{% block container %}
File "/Users/blysik/Documents/git/puppetboard/puppetboard/templates/layout.html", line 42, in block "container"
{% block row_fluid %}
File "/Users/blysik/Documents/git/puppetboard/puppetboard/templates/layout.html", line 44, in block "row_fluid"
{% block content %} {% endblock content %}
File "/Users/blysik/Documents/git/puppetboard/puppetboard/templates/nodes.html", line 30, in block "content"
{% for node in nodes %}
File "/Users/blysik/Documents/git/puppetboard/puppetboard/utils.py", line 47, in yield_or_stop
yield next(generator)
File "/Library/Python/2.7/site-packages/pypuppetdb/api/v2.py", line 69, in nodes
facts_timestamp=node['facts_timestamp'],
File "/Library/Python/2.7/site-packages/pypuppetdb/types.py", line 239, in init
self.catalog_timestamp = catalog_timestmap
NameError: global name 'catalog_timestmap' is not defined
This is just a test instance running on Mac OS X 10.8.4.
This causes all kinds of havoc on the /facts page:
mwapp_entitlement_0_status=<html><head><title>apache tomcat/6.0.26 - error report</title><style><!--h1 {font-family:tahoma,arial,sans-serif;color:white;background-color:#525d76;font-size:22px;} h2 {font-family:tahoma,arial,sans-serif;color:white;background-color:#525d76;font-size:16px;} h3 {font-family:tahoma,arial,sans-serif;color:white;background-color:#525d76;font-size:14px;} body {font-family:tahoma,arial,sans-serif;color:black;background-color:white;} b {font-family:tahoma,arial,sans-serif;color:white;background-color:#525d76;} p {font-family:tahoma,arial,sans-serif;background:white;color:black;font-size:12px;}a {color : black;}a.name {color : black;}hr {color : #525d76;}--></style> </head><body><h1>http status 401 - </h1><hr size="1" noshade="noshade"><p><b>type</b> status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>this request requires http authentication ().</u></p><hr size="1" noshade
Hi,
I've just tried out puppetboard and I get the following messages inside the log:
[Tue Nov 18 15:58:00.296193 2014] [:error] [pid 24445:tid 140375343712000] DEBUG:pypuppetdb.api:_query called with endpoint: mbean, path: com.puppetlabs.puppetdb.query.population:type=default,name=num-nodes, query: None, limit: None, offset: None, summarize_by None, count_by None, count_filter: None
[Tue Nov 18 15:47:54.158739 2014] [:error] [pid 24446:tid 140375385675520] DEBUG:pypuppetdb.api:_url called with endpoint: mbean and path: com.puppetlabs.puppetdb.query.population:type=default,name=num-nodes
[Tue Nov 18 15:47:54.159698 2014] [:error] [pid 24446:tid 140375385675520] INFO:urllib3.connectionpool:Starting new HTTPS connection (1): puppet-test01.smaatolabs.net
[Tue Nov 18 15:47:54.170741 2014] [:error] [pid 24446:tid 140375385675520] ERROR:pypuppetdb.api:Could not reach PuppetDB on puppet-test01.smaatolabs.net:8081 over HTTPS.
I'm wondering if there is really a connection problem or what I assume something like a change in the puppetdb API.
Currently I'm using version 0.0.4 of puppetboard and version 1.6.2 for puppetdb.
Could you confirm something? Or have any other hints what is going wrong here?
After cloning 0.0.4 running dev.py (or the former wsgi script for that matter) results in:
Traceback (most recent call last):
File "dev.py", line 4, in <module>
from puppetboard.app import app
File "/tmp/puppetboard/puppetboard/app.py", line 10, in <module>
from flask import (
ImportError: cannot import name stream_with_context
This is with py-flask-0.10.1 and py-flask-wtf-0.9.4 (not 0.8.4), however this used to work before. Did anything change, or what am I doing wrong? :)
When puppetboard shows a report - it does not show its status (ie. from puppet-dasboard: failed, changed, ok - red/blue/green).
That - and a summary "block" with all my hosts last status (ie. latest report from each host, divided into failed, changed, ok and unresponsive counts).
The results of a /fact/<fact>
is sorted by certname by default. It would be nice to be able to sort by value as well.
When puppetboard shows a report - it does not show its status (ie. from puppet-dasboard: failed, changed, ok - red/blue/green).
That - and a summary "block" with all my hosts last status (ie. latest report from each host, divided into failed, changed, ok and unresponsive counts).
I wish nodes whose catalog compilation failed would show in the node list.
I am getting the following stack trace error when I launch the console from the browser. Please help
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1836, in call
return self.wsgi_app(environ, start_response)
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python2.6/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functionsrule.endpoint
File "/root/puppetdashboard/puppetboard/puppetboard/app.py", line 108, in index
with_status=True)
TypeError: nodes() got an unexpected keyword argument 'unreported'
Hey,
Would be cool to be able to use query just by checking an andpoint but not writing a query.
It does make sense for factnames for example.
In your readme, under the section UWSGI + NGINX you have us starting uwsgi like so:
uwsgi --http :9090 --wsgi-file /var/www/puppetboard/wsgi.py
This does not open a UWSGI socket, so the proxy via NGINX does not work.
==> /var/log/nginx/error.log <== 2014/06/05 17:25:51 [error] 27833#0: *7 upstream timed out (110: Connection timed out) while reading response header from upstream, client: x.x.x.x, server: x.x.net, request: "GET / HTTP/1.1", upstream: "uwsgi://x.x.x.x:9090", host: "x.x.net"
You want something like:
uwsgi --socket :9090 --wsgi-file /var/www/puppetboard/wsgi.py
We are adding environmental awareness to PuppetDB and this tool should support that when it comes out.
For now this is targeted at PDB 2.0.0, which is targeted for a final release late May.
Here is the Epic covering this task: https://tickets.puppetlabs.com/browse/PDB-47
The docs will become available here as the feature progresses: http://docs.puppetlabs.com/puppetdb/master/
The facts piechart is hard to see when slices are very thin. Being able to hover over thin slices or click on the slices to drill down would be helpful.
I installed puppetboard on a new machine, set it up with wsgi.
/nodes was timing out, even though I upped PUPPETDB_TIMEOUT to 60:
[Mon Sep 16 15:04:30 2013] [error] [client 17.203.15.7] Timeout: HTTPConnectionPool(host='XXXX.com', port=8080): Request timed out. (timeout=10), referer: http://puppetboard.XXXX.com/facts
I was able to modify pypuppetdb/api/init.py and by hand set timeout=60 at:
def init(self, api_version, host='localhost', port=8080,
ssl=False, ssl_key=None, ssl_cert=None, timeout=60):
"""Initialises our BaseAPI object passing the parameters needed in
order to be able to create the connection strings, set up SSL and
timeouts and so forth."""
Obviously just a hack, but I'm not much of a python guy. Looking at app.py, it appears to be creating the puppetdb object properly, so I really don't know what's going on.
Just wanted to write a short howto make puppetboard work under passenger.
I would recommend the following simply be part of puppetboard:
standing in puppetboard checkout:
mkdir public
mkdir tmp
ln -s wsgi.py passenger_wsgi.py
And the apache vhost is as you want it, but this as a minimum (port 443 or 80 - your choice):
<VirtualHost *:80>
ServerName puppetboard.example.tld
DocumentRoot /var/www/puppetboard/public
RackAutoDetect On
Alias /static /var/www/puppetboard/static
<Directory /var/www/puppetboard/>
Options None
Order allow,deny
allow from all
Also - if you are using CentOS 6 (or RHEL6) all python modules are in the EPEL repo - except pypuppetdb-0.0.2 and python-jinja2 needs to be v2.7+
From what I gather, puppetboard can only run in /
https://github.com/nedap/puppetboard/blob/master/puppetboard/app.py#L86
@app.route('/')
def index():
We'd like to be able to move it elsewhere when reverse proxying, right now all URLs and CSS is broken.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.