簡體   English   中英

Golang panic:接口轉換:interface {} is nil, not string

[英]Golang panic: interface conversion: interface {} is nil, not string

我嘗試創建 CA 配置文件、證書和私鑰,我在 go 中使用cfssl命令並嘗試模擬來自

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

這是我的代碼片段

package main

import (
    "bytes"
    "fmt"
    "io"
    "os/exec"

    "github.com/cloudflare/cfssl/log"

    "encoding/json"
    "io/ioutil"
    "os"

    "github.com/cloudflare/cfssl/cli"
    "github.com/cloudflare/cfssl/cli/bundle"
    "github.com/cloudflare/cfssl/cli/certinfo"
    "github.com/cloudflare/cfssl/cli/gencert"
    "github.com/cloudflare/cfssl/cli/gencrl"
    "github.com/cloudflare/cfssl/cli/genkey"
    "github.com/cloudflare/cfssl/cli/info"
    "github.com/cloudflare/cfssl/cli/ocspdump"
    "github.com/cloudflare/cfssl/cli/ocsprefresh"
    "github.com/cloudflare/cfssl/cli/ocspserve"
    "github.com/cloudflare/cfssl/cli/ocspsign"
    printdefaults "github.com/cloudflare/cfssl/cli/printdefault"
    "github.com/cloudflare/cfssl/cli/revoke"
    "github.com/cloudflare/cfssl/cli/scan"
    "github.com/cloudflare/cfssl/cli/selfsign"
    "github.com/cloudflare/cfssl/cli/serve"
    "github.com/cloudflare/cfssl/cli/sign"
    "github.com/cloudflare/cfssl/cli/version"

    //  err "github.com/hyperledger/fabric/cop/errors"

    "google.golang.org/grpc"
)

func main() {

    var participantFile string = "key.pem"
    // file, err := os.Open("conf/ca-csr.json")
    // if err != nil {
    //  log.Fatalf("missing config file: %v", err)
    // }
    // defer file.Close()
    // s, err := ioutil.ReadAll(file)
    // if err != nil {
    //  log.Fatalf("could not read config file: %v", err)
    // }

    csr := `{
        "CN": "admin",
        "key": {
          "algo": "rsa",
          "size": 2048
        },
        "names": [
          {
            "C": "US",
            "L": "Portland",
            "O": "system:masters",
            "OU": "Kubernetes The Hard Way",
            "ST": "Oregon"
          }
        ]
      }`

    //csr := string([]byte(s[:]))
    GenCert(csr, participantFile)
}

var cfsslCmds = map[string]*cli.Command{
    "bundle":         bundle.Command,
    "certinfo":       certinfo.Command,
    "sign":           sign.Command,
    "serve":          serve.Command,
    "version":        version.Command,
    "genkey":         genkey.Command,
    "gencert":        gencert.Command,
    "gencrl":         gencrl.Command,
    "ocspdump":       ocspdump.Command,
    "ocsprefresh":    ocsprefresh.Command,
    "ocspsign":       ocspsign.Command,
    "ocspserve":      ocspserve.Command,
    "selfsign":       selfsign.Command,
    "scan":           scan.Command,
    "info":           info.Command,
    "print-defaults": printdefaults.Command,
    "revoke":         revoke.Command,
}

// CertMgr is the default certificate manager
type CertMgr struct {
    rootPath            string
    participantFilePath string
    cert                []byte
    grpcServer          *grpc.Server
}

type output struct {
    Cert string
}

type gencertOutput struct {
    cert []byte
    csr  []byte
    key  []byte
}

func GenCert(csr string, participantFile string) {
    var args []string

    gencertCmd := cfsslCmds["gencert"]
    var c cli.Config
    c.IsCA = true

    args = append(args, csr)

    out := ExecuteCommand(args, gencertCmd, c)

    var gencertOut map[string]interface{}
    json.Unmarshal([]byte(out), &gencertOut)

    var writeJSON output
    writeJSON.Cert = gencertOut["cert"].(string)
    jsonOut, _ := json.Marshal(writeJSON)

    ioutil.WriteFile(participantFile, jsonOut, 0644)

    return

}

func ExecuteCommand(args []string, command *cli.Command, c cli.Config) string {

    cfsslJSONCmd := exec.Command("cfssljson", "-bare")

    old := os.Stdout
    r, w, _ := os.Pipe()
    os.Stdout = w

    err := command.Main(args, c) // Execute command
    if err != nil {
        log.Error(err)
    }

    outC := make(chan string)
    // copy the output in a separate goroutine so printing can't block indefinitely
    var buf bytes.Buffer
    go func() {
        io.Copy(&buf, r)
        cfsslJSONCmd.Stdin = &buf
        outC <- buf.String()
    }()

    w.Close()

    out := <-outC
    outByte := []byte(out)

    tmpFile, _ := ioutil.TempFile("", "tmp")
    defer os.Remove(tmpFile.Name())
    if _, err = tmpFile.Write(outByte); err != nil {
        fmt.Println("err: ", err)
    }

    os.Stdin = tmpFile
    os.Stdout = old // restoring the real stdout

    err = cfsslJSONCmd.Run() // Execute cfssljson -bare <prefix>
    if err != nil {
        log.Error(err)
    }

    return out // To be used to store in participant file
}

我收到了那個錯誤

[ERROR] open {
                "CN": "admin",
                "key": {
                  "algo": "rsa",
                  "size": 2048
                },
                "names": [
                  {
                        "C": "US",
                        "L": "Portland",
                        "O": "system:masters",
                        "OU": "Kubernetes The Hard Way",
                        "ST": "Oregon"
                  }
                ]
          }: no such file or directory
2022/03/25 19:23:39 [ERROR] exit status 1
panic: interface conversion: interface {} is nil, not string

goroutine 1 [running]:
main.GenCert({0xb9179c, 0xda}, {0xb3a3f3, 0x7})
        /home/Documents/git-repo/kunets-vpc-test/main.go:126 +0x229
main.main()
        /home/Documents/git-repo/kunets-vpc-test/main.go:70 +0x31
 

任何幫助建議將不勝感激,非常感謝!

我認為你在 goroutine 運行時關閉 w 並且它以某種方式突然結束進程或讀取命令 output。嘗試通過打印“out”來確認,如果這是問題,請使用 defer 關閉 w

使用安全轉換以避免恐慌並使用 spew.Dump(需要外部庫)檢查數據。

或者使用調試器

variable, ok := something.(string)
if !ok {
  // cant convert to string, now what???
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM