code: func (c *Client) AddMember(name string, peerAddrs string) ([]Member, error) {
  	// Parse the peer address, required to add the client URL later to the list
  	// of endpoints for this client. Parsing as a first operation to make sure that
  	// if this fails no member addition is performed on the etcd cluster.
  	parsedPeerAddrs, err := url.Parse(peerAddrs)
  	if err != nil {
  		return nil, errors.Wrapf(err, "error parsing peer address %s", peerAddrs)
  	}
  
  	cli, err := clientv3.New(clientv3.Config{
  		Endpoints:   c.Endpoints,
  		DialTimeout: 20 * time.Second,
  		TLS:         c.TLS,
  	})
  	if err != nil {
  		return nil, err
  	}
  	defer cli.Close()
  
  	// Adds a new member to the cluster
  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  	resp, err := cli.MemberAdd(ctx, []string{peerAddrs})
  	cancel()
  	if err != nil {
  		return nil, err
  	}
  
  	// Returns the updated list of etcd members
  	ret := []Member{}
  	for _, m := range resp.Members {
  		// fixes the entry for the joining member (that doesn't have a name set in the initialCluster returned by etcd)
  		if m.Name == "" {
  			ret = append(ret, Member{Name: name, PeerURL: m.PeerURLs[0]})
  		} else {
  			ret = append(ret, Member{Name: m.Name, PeerURL: m.PeerURLs[0]})
  		}
  	}
  
  	// Add the new member client address to the list of endpoints
  	c.Endpoints = append(c.Endpoints, GetClientURLByIP(parsedPeerAddrs.Hostname()))
  
  	return ret, nil
  }
docs: // AddMember notifies an existing etcd cluster that a new member is joining