mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			50 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			50 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| package mysql
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"crypto/md5"
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 
 | |
| 	"github.com/go-sql-driver/mysql"
 | |
| 	"golang.org/x/net/proxy"
 | |
| )
 | |
| 
 | |
| // registerProxyDialerContext registers a new dialer context to be used by mysql when the proxy network is
 | |
| // specified in the connection string
 | |
| func registerProxyDialerContext(protocol, cnnstr string, dialer proxy.Dialer) (string, error) {
 | |
| 	// the mysqlDialer contains the true network used behind the scenes
 | |
| 	mysqlDialer, err := getProxyDialerContext(protocol, dialer)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 
 | |
| 	// the dialer context can be updated everytime the datasource is updated
 | |
| 	// have a unique network per connection string
 | |
| 	hash := fmt.Sprintf("%x", md5.Sum([]byte(cnnstr)))
 | |
| 	network := "proxy-" + hash
 | |
| 	mysql.RegisterDialContext(network, mysqlDialer.DialContext)
 | |
| 
 | |
| 	return network, nil
 | |
| }
 | |
| 
 | |
| // mySQLContextDialer turns a golang proxy driver into a MySQL proxy driver
 | |
| type mySQLContextDialer struct {
 | |
| 	dialer  proxy.ContextDialer
 | |
| 	network string
 | |
| }
 | |
| 
 | |
| // getProxyDialerContext returns a context dialer that will send the request through to the secure socks proxy
 | |
| func getProxyDialerContext(actualNetwork string, dialer proxy.Dialer) (*mySQLContextDialer, error) {
 | |
| 	contextDialer, ok := dialer.(proxy.ContextDialer)
 | |
| 	if !ok {
 | |
| 		return nil, fmt.Errorf("mysql proxy creation failed")
 | |
| 	}
 | |
| 	return &mySQLContextDialer{dialer: contextDialer, network: actualNetwork}, nil
 | |
| }
 | |
| 
 | |
| // DialContext implements the MySQL requirements for a proxy driver, and uses the underlying golang proxy driver with the assigned network
 | |
| func (d *mySQLContextDialer) DialContext(ctx context.Context, addr string) (net.Conn, error) {
 | |
| 	return d.dialer.DialContext(ctx, d.network, addr)
 | |
| }
 |