Giter Site home page Giter Site logo

localega-helm's Introduction

LocalEGA-helm

License: GPL v3 GitHub version

Table of Contents

Helm chart to deploy LocalEGA to any kubernetes cluster.

Prerequisites

Before deploying the Helm charts HELM should be initialized and the tiller installed, following these instructions.

Download the helm chart

git clone https://github.com/NBISweden/LocalEGA-helm.git

Or

helm repo add ega-charts https://nbisweden.github.io/LocalEGA-helm/
helm update
helm fetch --untar ega-charts/localega

N.B: If you use git clone to get the charts you will have to prefix localega in the example command lines below with ega-charts/.

When deploying a dev environment for the first time you need to create the secrets using the legainit utility from LocalEGA-deploy-init. Follow the instructions in that repository and install the command line utility. After it has been installed use:

legainit --config-path localega/config
# legainit --config-path ega-charts/localega/config # If cloned with git

or if you want to include generate fake CEGA credentials use:

legainit --cega --config-path localega/config

Optional, add S3 storage

LocalEGA relies on a S3 type backend storage as data archive.
If the kubernetes environment doesn't supply a S3 storage it can be added using either minio or ceph.

Minio

See the documentation for how to configure minio.
More specifically the size of each backing volume and if minio should run in distributed mode or not.

If you set up all secrets with the legainit program grab the values for S3_access and S3_secret from the localega/config/trace.yml file.

helm install --set accessKey=S3_access,secretKey=S3_secret,minioConfig.region=S3_region stable/minio

Installing the Chart

Edit the values.yaml file and specify the relevant hostnames for cega-mq, cega-users, SQL and the relevant data_storage parts.

The values that has to be configured in values.yaml are:

  • cega_users_host
  • cega_mq_host
  • cega_vhost
  • data_storage_url
  • s3_archive_bucket
  • s3_archive_region
  • (possibly disable persistence)

You can then install the localega chart via Helm CLI:

helm install --name <deployment name> --namespace <deployment namespace> localega -f localega/values.yaml -f localega/config/trace.yml

Configuration

localega chart

The following table lists the configurable parameters of the localega chart and their default values.

Parameter Description Default
config.broker_connection_attempts Connection attempts before timing out 30
config.broker_enable_ssl Use SSl for broker connection false
config.broker_heartbeat Heartbeat timeout balue 0
config.broker_port Local MQ acces port 5672
config.broker_retry_delay time in seconds between each connection attempt 10
config.broker_username username for accessing local MQ service guest
config.cega_users_host hostname of CEGA users service ""
config.cega_mq_host CEGA MQ hostname ""
config.cega_mq_ssl CEGA MQ uses SSL true
config.cega_vhost CEGA MQ vhost path ""
config.cega_port CEGA MQ acces port 5671
config.cega_mq_user CEGA MQ username ""
config.cega_users_user CEGA users username ""
config.postgres_pdata Path in container to postgres data folder location /ega
config.postgres_db_name Database name lega
config.postgres_host Database hostname or IP address Only needs to be set if the database is deployed searately
config.postgres_port Port to postgers service 5432
config.postgres_sslmode Use SSL for Database connection prefer
config.postgres_try Number of times to retry 5
config.postgres_try_interval Number of seconds between try attempts 1
config.postgres_in_user Database username for ingestion lega_in
config.postgres_out_user Database username for outgestion lega_out
config.data_storage_type Backend storage type, S3Storage or FileStorage S3Storage
config.s3_archive_url URL to S3 archive instance ""
config.s3_archive_bucket S3 archive bucket ""
config.s3_archive_region S3 archive region ""
config.s3_archive_chunk_size S3 chunk size in MB 16
config.data_storage_location Path to FileStorage volume /ega/data_archive
config.data_storage_mode File mode in storage volume 2750
config.s3_inbox_backend_url URL to S3 inbox backend ""
config.s3_inbox_backend_bucket S3 inbox backend bucket ""
config.s3_inbox_backend_region S3 inbox backend region ""
config.tls_certs boolean to create secrets that hold the TLS certificates true
config.tls_ca_root_file Name of the ca root file ca.crt
config.tls_cert_ending File ending to append after service name when loading TLS certificates .crt
config.tls_key_ending File ending to append after service name when loading TLS keys .key
persistence.enabled If true, create a Persistent Volume Claim for all services that require it true
persistence.storageClass Storage Class for all Persistent volume Claims, use "local-storage" for local backed storage ""
revisionHistory number of old ReplicaSets to retain to allow rollback 3
networkPolicy.create boolean that enables creation of network policies false
networkPolicy.cegaMqBroker block that specifies the egress rules for accessing the CEGA MQ server 0.0.0.0/0
networkPolicy.postgres block that specifies the egress rules for accessing an external postgres server 0.0.0.0/0
networkPolicy.S3Storage block that specifies the egress rules for accessing the external S3 server 0.0.0.0/0
secrets.cega_users_pass Password to CEGA users sevice ""
secrets.cega_mq_pass Password for CEGA MQ service ""
secrets.mq_pass Password for Localega MQ ""
secrets.mq_password_hash Hashed password for Localega MQ ""
secrets.pgp_passphrase private LocalEGA PGP passphrase ""
secrets.shared_pgp_password Shared LocalEGA PGP password ""
secrets.pg_in_password Password to LocalEGA sql database for ingestion ""
secrets.pg_out_password Password to LocalEGA sql database for outgestion ""
secrets.s3_archive_access_key Access key to S3 archive ""
secrets.s3_archive_secret_key Secret key to S3 archive ""
secrets.token jwt token for testing file download via dataedge ``
secrets.s3_inbox_backend_access_key Access key to S3 inbox backend ""
secrets.s3_inbox_backend_secret_key Secret key to S3 inbox backend ""
ingress.deploy Create ingress for data out components when set to true false
ingress.hostname The hostname that will be used in the ingress path ""
ingress.tls Boolean that controls whether TLS should be enabled for the ingress true
ingress.secretName Name of the secret that holds the TLS certificates, the secret must be manuallly created unless cert-manager is installed ""
ingress.issuer Name of the issuer to use when requesting the TLS certifiactes, requires that cert-manager is installed and configured ""
filedatabase_host External filedatabase host ""
filedatabase_port External filedatabase port 9059
keys_host External keys host ""
keys_port External keys port 9095
dataedge_host External dataedge host ""
dataedge_port External dataedge port 9050
res_host External res host ""
res_port External res port 9090
dataedge.deploy Set to false if not using a dataedge service true
dataedge.replicaCount desired number of replicas 1
dataedge.repository dataedge container image repository cscfi/ega-dataedge
dataedge.imageTag dataedge container image version "latest"
dataedge.imagePullPolicy dataedge container image pull policy IfNotPresent
dataedge.keystorePass keystore password dataedge
dataedge.port dataedge container port 8080
dataedge.servicePort dataedge service port 9059
filedatabase.deploy Set to false if not using a filedatabase service true
filedatabase.replicaCount desired number of replicas 1
filedatabase.repository filedatabase container image repository cscfi/ega-filedatabase
filedatabase.imageTag filedatabase container image version "latest"
filedatabase.imagePullPolicy filedatabase container image pull policy IfNotPresent
filedatabase.port filedatabase container port 8080
filedatabase.servicePort filedatabase service port 9050
filedatabase.debug filedatabase debug port 5050
filedatabase.keystorePass keystore password filedatabase
finalize.deploy Set to false if not using a finalize service true
finalize.repository inbox container image repository egarchive/lega-base
finalize.imageTag inbox container image version stable
finalize.imagePullPolicy inbox container image pull policy IfNotPresent
inbox.deploy Set to false if not using a inbox service true
inbox.repository inbox container image repository egarchive/lega-inbox
inbox.imageTag inbox container image version stable
inbox.imagePullPolicy inbox container image pull policy IfNotPresent
inbox.inboxPath Path on mounted volume for inbox data /
inbox.replicaCount desired number of inboxes 1
inbox.persistence.existingClaim inbox data Persistent Volume existing claim name ""
inbox.persistence.storageSize inbox persistent volume size 1Gi
inbox.keystorePass keystore password for the mina inbox inbox
ingest.deploy Set to false if not using a ingest service true
ingest.repository inbox container image repository egarchive/lega-base
ingest.imageTag inbox container image version stable
ingest.imagePullPolicy inbox container image pull policy IfNotPresent
ingest.replicaCount desired number of ingest workers 1
keys.deploy Set to false if using a external keyserver true
keys.repository Keyserver container image repository cscfi/ega-keyserver
keys.imageTag Keyserver container image version "latest"
keys.imagePullPolicy Keyserver container image pull policy IfNotPresent
keys.port Keyserver port 8080
keys.servicePort Keyserver service port 9095
keys.keystorePass keystore password keys
mq.deploy Set to false if using an external message queue service true
mq.repository rabbitmq container image repository egarchive/lega-mq
mq.imageTag rabbitmq container image pull policy stable
mq.imagePullPolicy rabbitmq container image pull policy IfNotPresent
mq.persistence.existingClaim rabbitmq data Persistent Volume existing claim name ""
mq.persistence.storageSize rabbitmq persistent volume size 1Gi
mq.port rabbitmq port 5672
mq.metrics.enabled enable metrics for rabbirmq service true
mq.metrics.repository rabbitmq metrics exporter repository kbudde/rabbitmq-exporter
mq.metrics.imageTag rabbitmq metrics exporter version v0.29.0
mq.metrics.imagePullPolicy rabbitmq metrics exporter image pull policy IfNotPresent
postgres.deploy Set to false if using a external database true
postgres.repository postgreSQL container image repository egarchive/lega-db
postgres.imageTag postgreSQL container image version stable
postgres.imagePullPolicy postgreSQL container image pull policy IfNotPresent
postgres.persistence.existingClaim postgres data Persistent Volume existing claim name ""
postgres.persistence.storageSize postgres persistent volume size 1Gi
postgres.metrics.enabled enable metrics for postgreSQL service true
postgres.metrics.repository postgreSQL metrics exporter repository wrouesnel/postgres_exporter
postgres.metrics.imageTag postgreSQL metrics exporter version v0.4.6
postgres.metrics.imagePullPolicy postgreSQL metrics exporter image pull policy IfNotPresent
res.deploy Set to false if not using a message re-encryption service true
res.repository RES container image repository cscfi/ega-res
res.imageTag RES container image version "latest"
res.imagePullPolicy RES container image pull policy IfNotPresent
res.replicaCount desired number of RES containers 1
res.port res container port 8080
res.servicePort res service port 9090
res.debug res debug port 5058
res.keystorePass keystore password res
s3inbox.deploy Set to true if an s3 inbox is to be used false
s3inbox.repository s3inbox container image repository nbisweden/ega-s3inbox
s3inbox.imageTag s3inbox container image version "0.1"
s3inbox.imagePullPolicy s3inbox container image pull policy Always
s3inbox.replicaCount desired number of s3inbox containers 1
s3inbox.port s3inbox container port 443
s3inbox.servicePort s3inbox service port 443
s3inbox.use_credentials_file Set to true if a credentials file is used false
verify.deploy Set to false if not using a message verify service true
verify.repository inbox container image repository egarchive/lega-base
verify.imageTag inbox container image version stable
verify.imagePullPolicy inbox container image pull policy IfNotPresent
verify.replicaCount desired number of verify containers 1
tester.run run end-to-end test if true false
tester.repository inbox container image repository nbisweden/lega-tester
tester.imageTag inbox container image version latest
tester.imagePullPolicy inbox container image pull policy Always

logging chart

The following table lists the configurable parameters of the logging chart and their default values.

Parameter Description Default
config.broker_connection_attempts Connection attempts before timing out 30
config.elastichost Hostname for the Elasticsearch master elasticsearch-master.elasticsearch
config.elasticport Port for connecting to the elsaticsearch master 9200
fluentbit.name Value for label component fluentbit
fluentbit.deploy Set to false to not deploy fluentbit true
fluentbit.repository fluentbit container image repository true
fluentbit.imageTag fluentbit container image version 1.3.3
fluentbit.imagePullPolicy fluentbit container image pull policy Always

Install fake CEGA

Unless you cloned the git repo you need to download the cega chart:

helm fetch --untar ega-charts/cega

Copy the relevant files from the config folder created by the init script.

cp localega/config/users.json localega/config/cega.* cega/config
mkdir cega/config/certs
cp localega/config/certs/{cega-*,root.ca.crt} cega/config/certs/

You can install the cega chart via Helm CLI:

helm install --name <deployment name> --namespace <deployment namespace> cega -f localega/config/trace.yml

Setup logging

See the logging readme.

Uninstalling the Chart

You can uninstall the Chart via Helm CLI:

helm delete ${deployment name} --purge

localega-helm's People

Contributors

jbygdell avatar blankdots avatar jonandernovella avatar viklund avatar

Watchers

 avatar  avatar Erik Ylipää avatar James Cloos avatar Malin Klang avatar Björn avatar  avatar Jonas Hagberg avatar  avatar Richèl Bilderbeek avatar Per Johnsson avatar John Lövrot avatar Nanjiang Shu avatar Andreas Kähäri avatar Guilherme Borges Dias avatar  avatar Agustín Andrés Corbat avatar Martin Pippel avatar Juliana Assis avatar Dimitris Bampalikis avatar Oskar Vidarsson avatar Emilio Mármol Sánchez avatar  avatar

Forkers

umccr

localega-helm's Issues

cega-mq does not start

Expected Behavior

cega-mq should successfully mount the necessary volumes and start accordingly

Current Behavior

lega-se-testy-service-000  MountVolume.SetUp failed for volume "temp"
 : configmap references non-existent config key: cega.config

lega-se-testy-service-000  Unable to mount volumes for pod:timeout expired waiting for
 volumes to attach or mount for pod "cega"/"cega-mq-7845f789d6-l79qj". list of unmounted
 volumes=[temp]. list of unattached volumes=[cega-mq-entrypoint temp rabbitmq 
 default-token-lnzxx]

Context (Environment)

rke-openstack + legainit

Remove HostPath volumes

Description

HostPath volumes should be removes as they are not secure enough to be used.

Proposed solution

Remove HostPath volumes and add an example to the README on how to use the local volume provisioner that is GA as of k8s 1.14.0.

Definition of Done

HostPath volumes are replaces by LocalVolume volumes.

Defaults in values.yml for fakecega

Description

I'm trying to get local versions of CEGA and LEGA chatting with one another and having a hard time wrangling the config. What variables in values.yml (for fakecega and lega) need to be changed?

As of now, my values.yml looks like so:

config:
  log: "debug"
  broker_connection_attempts: 30
  broker_enable_ssl: "false"
  broker_heartbeat: 0
  broker_host: "lega-localega-mq" 
  broker_port: 5672
  broker_retry_delay: 10
  broker_username: "guest" # local broker user
  broker_vhost: "/"
  cega_users_host: http://cega-users
  cega_users_endpoint: "/lega/v1/legas/users/%s?idType=username" # "/lega/v1/legas/users/%s?idType=username"
  cega_endpoint_json: "response.result"
  cega_mq_host: "cega-mq" # FQDN to cega mq host
  cega_vhost: "/"
  cega_port: 5672
  cega_username: "cega" # cega user
  keyserver_host: "lega-localega-keys" # defaults to localega-keys
  keyserver_endpoint: "/keys/retrieve/%s/private/bin?idFormat=hex"
  postgres_db_name: "lega"
  postgres_db_schema: "local_ega"
  postgres_host: "lega-localega-db" # defaults to localega-db
  postgres_try: 30
  postgres_sslmode: "prefer"
  postgres_user: "lega"
  res_host: "lega-localega-res" # defaults to localega-res
  filedatabase_host: "lega-localega-filedatabase" # defaults to localega-filedatabase
  dataedge_host: "lega-localega-dataedge" # defaults to localega-dataedge
  data_storage_type: "S3Storage" # S3Storage or FileStorege
  data_storage_url: "https://umccr-localega-dev.s3.amazonaws.com" # URl to S3 instance
  data_storage_s3_bucket: "umccr-localega-dev"
  data_storage_s3_region: "ap-southeast-2"
  data_storage_s3_chunk_size: 4 # Chunk size in MB
  data_storage_location: "/ega/data_archive" # path to data archive volume
  data_storage_mode: 2750

persistence: 
  enabled: true

secrets:
  cega_creds: "cega"
  cega_mq_pass: "lega"
  pgp_passphrase: "guest"
  shared_pgp_password: "guest"
  mq_password: "lega"
  postgres_password: "lega"
  s3_access_key: "xxxx"
  s3_secret_key: "xxxxx"

I have a helm installation of fakecega running as cega and am able to resolve these names.

A few other issues I've run into:

  • There are hardcoded hashes in cega/conf/cega.json what values do these correspond to? Do these have anything to do with what's in values.yml?
  • I'm also unsure what cega_creds cega_mq_pass mq_password refer to since they are undocumented in the readme.
  • What does the dummy user password hash in dummy.yml correspond to?
  • Should I be using values from trace.yml? Can we use these programmatically?

Proposed solution

  • Document default/hardcoded hashes or generate them on the fly
  • Document cega_creds cega_mq_pass mq_password
  • A simple procedure to spin up CEGA and LEGA together such that the defaults work -- ie if cega and lega are spun up with particular names in helm it "just works".

Definition of Done

  • Documentation and defaults updated

Great work on this by the way! I'm looking forward to getting these components singing! 🚀

Healthchecks are failing

Expected Behavior

Healthchecks for the DB should work

Current Behavior

Checks fail due to wrong user

Possible Solution

Steps to Reproduce

Context (Environment)

Readiness probe fails in Inbox

Expected Behavior

Inbox Readiness should not fail in OpenSSH inbox.

Current Behavior

There is an error message:

Did not receive identification string from x.x.x.x port 56420
[MQ] Loading configuration /etc/ega/mq.conf
Did not receive identification string from x.x.x.x port 56458
[MQ] Loading configuration /etc/ega/mq.conf
Did not receive identification string from x.x.x.x port 56510
[MQ] Loading configuration /etc/ega/mq.conf
Did not receive identification string from x.x.x.x port 56552

Possible Solution

     readinessProbe:
          exec:
            command: 
            - sh
            - -ec
            - ps -ef | grep ega-sshd
          initialDelaySeconds: 30
          periodSeconds: 15

or maybe it should be different depending on the inbox Mina or OpenSSH

Steps to Reproduce

  1. Start Helm charts
  2. wait till inbox starts
  3. kubectl logs -f -n lega lega-localega-inbox-xxxxx

Context (Environment)

Started the Helm charts with OpenSSH inbox

Configurable PV access modes

Description

The Helm chart should allow the possibility of configurable PV access modes

Proposed solution

Templating access modes in the resource definitions

Definition of Done

The chart passed the tests and works as expected.

Move fake CEGA

Move fake CEGA to either a subchart or a separate chart.

FileStorage backend for Archive fails with permission denied

Expected Behavior

ingest and verify should be able to use a co-located archive on a hostPath

Current Behavior

When setting in values.yaml the following config parameters:

data_storage_type: "FileStorage"
data_storage_location: "/ega/archive" # path to data archive volume
data_storage_mode: 2750

ingest service fails with:

[lega.ingest][ INFO ] (L82) [FileStorage] Moving the rest of 2019-07-18_04-37-15.c4ga to /000/000/000/000/000/000/01
[lega.utils.db][ERROR ] (L246) Exception: <class 'PermissionError'> in /usr/local/lib/python3.6/site-packages/lega/utils/db.py on line: 277
[lega.utils.db][ERROR ] (L249) PermissionError(13, 'Permission denied') (from user: False)
[lega.utils.db][DEBUG ] (L131) Setting error for 1: [Errno 13] Permission denied: '/ega/archive/lega' | Cause: None

The ingest service fails to access the volume due to group permissions.

Possible Solution

  1. Add volumeMounts to both ingest and verify based on .Values.config.data_storage_type equal to FileStorage.
  2. Add volume to both ingest and verify based on .Values.config.data_storage_type equal to FileStorage also make it co-located aware.
  3. The first two steps might not be enough as even though the file might be ingested it still needs to share directory with verify service
  4. Setting node affinity for verify to be on the same node as ingest. Might need the same for res service.

Steps to Reproduce

  1. Set in values.yaml the values as pointed in Current Behavior above
  2. Run e2e tester

Context (Environment)

Run helm charts with FileStorage as archive.

Segfault in ega_ssh_keys

Expected Behavior

Users are unable to login to inbox because the ega_ssh_keys binary is segfaulting during operation.

Current Behavior

[root@lega-localega-inbox-66f95f4f45-vt9ks ega]# /usr/local/bin/ega_ssh_keys lega
Segmentation fault (core dumped)
[root@lega-localega-inbox-66f95f4f45-vt9ks ega]# /usr/local/bin/ega_ssh_keys dummy
Segmentation fault (core dumped)

After compiling with debug symbols:

(gdb) bt
#0  0x00007f0e63090f19 in vfprintf () from /lib64/libc.so.6
#1  0x00007f0e630b52cb in vsprintf () from /lib64/libc.so.6
#2  0x00007f0e63097467 in sprintf () from /lib64/libc.so.6
#3  0x00000000004012d0 in main (argc=<optimized out>, argv=<optimized out>) at keys.c:38

Line 38 in keys.c:

  if(sprintf(endpoint, options->cega_endpoint_username, username) < 0){ D1("Endpoint formatting error"); return 2; }

auth.conf is as follows:

[root@lega-localega-inbox-66f95f4f45-vt9ks /]# cat /etc/ega/auth.conf
##################
# Central EGA
##################

cega_endpoint_username = cega-users/lega/v1/legas/users/%s?idType=username
cega_endpoint_uid = cega-users/lega/v1/legas/users/%u?idType=uid
cega_creds = lega:cega
cega_json_prefix = response.result

##################
# NSS & PAM
##################
#prompt = Knock Knock:
#ega_shell = /bin/bash
#ega_uid_shift = 10000

ega_gid = 997
chroot_sessions = yes
db_path = /run/ega.db
ega_dir = /ega/inbox
ega_dir_attrs = 2750 # rwxr-s---
#ega_dir_umask = 027 # world-denied

Possible Solution

My guess here is that options is uninitialised.

Steps to Reproduce

  1. Shell into an inbox container kubectl exec -it *inbox* bash
  2. Run /usr/local/bin/ega_ssh_keys lega or /usr/local/bin/ega_ssh_keys dummy

Context (Environment)

Environment spun up via the helm chart.

Set up test matrix in github actions

Description

Definition of Done

Test all inbox/storage combinations
mina + filesystem archive
mina + s3 archive
s3inbox +s3 archive

How to test

Roll deployment on config update

Description

We should roll the depoyment on configmap chages

Proposed solution

Keep ttrack of the checksum for the CM i question and recreate the pod if the checksum changes.

Definition of Done

Changes to a configmap will recreate all related pods.

S3 secrets mismatch

Expected Behavior

S3 secrets should both contain the same contents.

Current Behavior

kubectl describe secret localega-s3-keys -n lega
Name:         localega-s3-keys
Namespace:    lega

s3_access_key:  16 bytes
s3_secret_key:  32 bytes

kubectl describe secret myminio -n lega
Name:         myminio
Namespace:    lega

accesskey:  18 bytes
secretkey:  34 bytes 

Interestingly, myminio secret is including the "" around the actual secret.

Possible Solution

The latest Minio Helm chart seems to be broken. We might need to downgrade or fix a version in our deployments.

Context (Environment)

Cluster deployed using rke-openstack and legainit

NAME   	REVISION	UPDATED                 	STATUS  	CHART         	APP VERSION                 	NAMESPACE
cega   	1       	Mon Apr 15 16:24:32 2019	DEPLOYED	cega-0.1.2    	1.0                         	cega     
lega   	1       	Mon Apr 15 16:24:34 2019	DEPLOYED	localega-0.2.3	1.0                         	lega     
myminio	1       	Mon Apr 15 16:24:25 2019	DEPLOYED	minio-2.4.12  	RELEASE.2019-04-09T01-22-30Z	lega 

End to End testing

Description

We would like add an end to end testing as part of the deployment that tests:

  1. Encrypts a file
  2. Encrypted file can be ingested
  3. Mocks the stable_id generation
  4. Mocks the assignation of files to datasets for permissions
  5. Retrieves and compares the file via RES using the session key and IV from generation
  6. Retrieves and compares the file from DataEdge using JWT token

Scripts for testing available here: https://gist.github.com/blankdots/bb004abdd6faaed2e59d5687f619eb1e

Images used for M4: EGA-archive/LocalEGA#7 (comment)

Needs a container added to the network for testing.

Definition of Done

Test run in CI on each PR.

How to test

Peer review and testing scenario is successful.

Add RBAC rules to chart

Description

Add RBAC and PSP rules to the helm chart

Definition of Done

Chart can be deployed in a namespace with minimal privileges

How to test

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.