Golang client with TLS

Can you help.
How I can connect to my dgraph alpha using tls and golang client?

Server ip 197.0.0.1

TLS key and crt in folder ./tls/
rw-rw-r-- 1 gigihont gigihont 1168 Feb 19 09:29 client.dgraphuser.crt
-rw------- 1 gigihont gigihont 1679 Feb 19 09:29 client.dgraphuser.key

Program in ./connect.go

This code doesn’t work. Where is my mistake?

File main.go

package main

import (

  "context"

  "crypto/tls"

  "encoding/json"

  "fmt"

  "log"

  "time"

  "github.com/dgraph-io/dgo/v2"

  "github.com/dgraph-io/dgo/v2/protos/api"

  "github.com/dgraph-io/dgraph/x"

)

//School struct about school

type School struct {

  Name  string   `json:"name,omitempty"`

  DType []string `json:"dgraph.type,omitempty"`

}

type loc struct {

  Type   string    `json:"type,omitempty"`

  Coords []float64 `json:"coordinates,omitempty"`

}

// If omitempty is not set, then edges with empty values (0 for int/float, "" for string, false

// for bool) would be created for values not specified explicitly.

//Person struct about person

type Person struct {

  UID      string     `json:"uid,omitempty"`

  Name     string     `json:"name,omitempty"`

  Age      int        `json:"age,omitempty"`

  Dob      *time.Time `json:"dob,omitempty"`

  Married  bool       `json:"married,omitempty"`

  Raw      []byte     `json:"raw_bytes,omitempty"`

  Friends  []Person   `json:"friend,omitempty"`

  Location loc        `json:"loc,omitempty"`

  School   []School   `json:"school,omitempty"`

  DType    []string   `json:"dgraph.type,omitempty"`

}

var tlsConf x.TLSHelperConfig = x.TLSHelperConfig{

  CertDir:          "tls",

  CertRequired:     true,

  Cert:             "client.dgraphuser.crt",

  Key:              "client.dgraphuser.key",

  ServerName:       "192.168.1.38",

  RootCACert:       "ca.crt",

  ClientAuth:       "",

  UseSystemCACerts: false,

}

//LoadServerTLSConfig function for connections

func LoadServerTLSConfig(conf x.TLSHelperConfig) (*tls.Config, error) {

  return x.GenerateServerTLSConfig(&conf)

}

func main() {

  tlsCon, err := LoadServerTLSConfig(tlsConf)

  conn, err := x.SetupConnection("192.168.1.38", tlsCon, false)

  x.Checkf(err, "While trying to setup connection to Dgraph alpha.")

  defer conn.Close()

  dc := api.NewDgraphClient(conn)

  dg := dgo.NewDgraphClient(dc)

  dob := time.Date(1980, 01, 01, 23, 0, 0, 0, time.UTC)

  // While setting an object if a struct has a Uid then its properties in the graph are updated

  // else a new node is created.

  // In the example below new nodes for Alice, Bob and Charlie and school are created (since they

  // don't have a Uid).

  p := Person{

    UID:     "_:alice",

    Name:    "Alice",

    Age:     26,

    Married: true,

    DType:   []string{"Person"},

    Location: loc{

      Type:   "Point",

      Coords: []float64{1.1, 2},

    },

    Dob: &dob,

    Raw: []byte("raw_bytes"),

    Friends: []Person{{

      Name:  "Bob",

      Age:   24,

      DType: []string{"Person"},

    }, {

      Name:  "Charlie",

      Age:   29,

      DType: []string{"Person"},

    }},

    School: []School{{

      Name:  "Crown Public School",

      DType: []string{"Institution"},

    }},

  }

  op := &api.Operation{}

  op.Schema = `

    name: string @index(exact) .

    age: int .

    married: bool .

    loc: geo .

    dob: datetime .

    Friend: [uid] .

    type: string .

    coords: float .

    type Person {

      name: string

      age: int

      married: bool

      Friend: [Person]

      loc: Loc

    }

    type Institution {

      name: string

    }

    type Loc {

      type: string

      coords: float

    }

  `

  ctx := context.Background()

  if err := dg.Alter(ctx, op); err != nil {

    log.Fatal(err)

  }

  mu := &api.Mutation{

    CommitNow: true,

  }

  pb, err := json.Marshal(p)

  if err != nil {

    log.Fatal(err)

  }

  mu.SetJson = pb

  response, err := dg.NewTxn().Mutate(ctx, mu)

  if err != nil {

    log.Fatal(err)

  }

  // Assigned uids for nodes which were created would be returned in the response.Uids map.

  variables := map[string]string{"$id1": response.Uids["alice"]}

  q := `query Me($id1: string){

    me(func: uid($id1)) {

      name

      dob

      age

      loc

      raw_bytes

      married

      dgraph.type

      friend @filter(eq(name, "Bob")){

        name

        age

        dgraph.type

      }

      school {

        name

        dgraph.type

      }

    }

  }`

  resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)

  if err != nil {

    log.Fatal(err)

  }

  type Root struct {

    Me []Person `json:"me"`

  }

  var r Root

  err = json.Unmarshal(resp.Json, &r)

  if err != nil {

    log.Fatal(err)

  }

  out, _ := json.MarshalIndent(r, "", "\t")

  fmt.Printf("%s\n", out)

}

File go.mod

module security.com/myapp

go 1.13

require (

  contrib.go.opencensus.io/exporter/jaeger v0.2.0 // indirect

  github.com/DataDog/datadog-go v3.4.0+incompatible // indirect

  github.com/DataDog/opencensus-go-exporter-datadog v0.0.0-20191210083620-6965a1cfed68 // indirect

  github.com/apache/thrift v0.13.0 // indirect

  github.com/dgraph-io/badger/v2 v2.0.1 // indirect

  github.com/dgraph-io/dgo v1.0.0

  github.com/dgraph-io/dgo/v2 v2.2.0

  github.com/dgraph-io/dgraph v1.2.1

  github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect

  github.com/hashicorp/golang-lru v0.5.4 // indirect

  github.com/pelletier/go-toml v1.6.0 // indirect

  github.com/pkg/errors v0.9.1 // indirect

  github.com/pkg/profile v1.4.0 // indirect

  github.com/prometheus/client_golang v1.4.1 // indirect

  github.com/prometheus/procfs v0.0.10 // indirect

  github.com/spf13/afero v1.2.2 // indirect

  github.com/spf13/cast v1.3.1 // indirect

  github.com/spf13/jwalterweatherman v1.1.0 // indirect

  github.com/spf13/pflag v1.0.5 // indirect

  github.com/spf13/viper v1.6.2 // indirect

  github.com/tinylib/msgp v1.1.1 // indirect

  github.com/uber/jaeger-client-go v2.22.1+incompatible // indirect

  go.opencensus.io v0.22.3 // indirect

  golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 // indirect

  golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect

  golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c // indirect

  google.golang.org/api v0.17.0 // indirect

  google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 // indirect

  google.golang.org/grpc v1.27.1

  gopkg.in/DataDog/dd-trace-go.v1 v1.21.0 // indirect

  gopkg.in/ini.v1 v1.52.0 // indirect

  gopkg.in/yaml.v2 v2.2.8 // indirect

)

$tree

.
β”œβ”€β”€ go.mod
β”œβ”€β”€ go.sum
β”œβ”€β”€ main.go
└── tls
    β”œβ”€β”€ ca.crt
    β”œβ”€β”€ client.dgraphuser.crt
    └── client.dgraphuser.key

$ go run main.go

2020/02/19 19:31:08 context deadline exceeded
While trying to setup connection to Dgraph alpha.
github.com/dgraph-io/dgraph/x.Checkf
        C:/Users/Vladimir/go/pkg/mod/github.com/dgraph-io/dgraph@v1.2.1/x/error.go:49
main.main
        C:/DgraphLern/GoClient/Program/Security/main.go:64
runtime.main
        c:/go/src/runtime/proc.go:203
runtime.goexit
        c:/go/src/runtime/asm_amd64.s:1357
exit status 1

Hi vladimir, We are looking at your post and will respond soon. Thanks.

I see two problems, and I will look into this more tomorrow:

  1. you are using the server code, you should instead use the client code. I will have to figure that out.
  2. You are not passing the port in the .SetupConncetion function.

Hello. Which port should I use with

192.168.1.38:9080

?

grpc port, 9080 or equivalent.

The following code works for me:

func setupTLSConnection() (*grpc.ClientConn, error) {
	b, err := ioutil.ReadFile("tls/ca.crt")
	if err != nil {
		return nil, err
	}

	cp := x509.NewCertPool()
	if !cp.AppendCertsFromPEM(b) {
		return nil, errors.New("credentials: failed to append certificates")
	}

	cert, err := tls.LoadX509KeyPair("tls/client.acl.crt", "tls/client.acl.key")
	if err != nil {
		return nil, err
	}

	config := &tls.Config{
		InsecureSkipVerify: false,
		RootCAs:            cp,
		Certificates:       []tls.Certificate{cert},
	}
	conn, err := grpc.Dial("localhost:9180", grpc.WithTransportCredentials(credentials.NewTLS(config)))
	if err != nil {
		return nil, err
	}

	return conn, nil
}

Let me know if you have any more questions.

1 Like

Thanks. Code works perfectly.