func AddEntries()

in entryMaker/oneCRL/oneCRL.go [453:651]


func AddEntries(records *Records, existing *Records, createBug bool, comment string) error {
	conf := config.GetConfig()

	issuerMap := make(map[string][]string)

	bugStyle := ""

	bugNum := -1

	shouldWrite := conf.Preview != "yes" && len(records.Data) > 0

	now := time.Now()
	nowString := now.Format("2006-01-02T15:04:05Z")

	// Check that we're correctly authenticated to Kinto
	if shouldWrite {
		err := checkKintoAuth(conf.KintoCollectionURL)

		if nil != err {
			return err
		}
	}

	// File a bugzilla bug - so we've got a bug URL to add to the kinto entries
	if shouldWrite && !conf.SkipBugzilla {
		bug := bugs.Bug{}
		bug.ApiKey = conf.BugzillaAPIKey
		blocks, err := strconv.Atoi(conf.BugzillaBlockee)
		if len(conf.BugzillaBlockee) != 0 {
			if nil == err {
				bug.Blocks = append(bug.Blocks, blocks)
			}
		}
		bug.Product = conf.BugProduct
		bug.Component = conf.BugComponent
		bug.Version = conf.BugVersion
		bug.Summary = fmt.Sprintf("CCADB entries generated %s", nowString)
		bug.Description = conf.BugDescription
		bug.Type = "task"

		bugNum, err = bugs.CreateBug(bug, conf)
		if err != nil {
			panic(err)
		}
		fmt.Printf("Added bug: %d\n", bugNum)
	}

	for _, record := range records.Data {
		// TODO: We don't need to build an issuer map if we're not outputting
		// entries directly. If we *do* need to do this, the functionality for
		// making revocations.txt style data should live in oneCRL.go
		if issuers, ok := issuerMap[record.IssuerName]; ok {
			issuerMap[record.IssuerName] = append(issuers, record.SerialNumber)
		} else {
			issuerMap[record.IssuerName] = []string{record.SerialNumber}
		}

		if record.Details.Bug == "" {
			record.Details.Bug = fmt.Sprintf("%s/show_bug.cgi?id=%d", conf.BugzillaBase, bugNum)
		}
		if record.Details.Created == "" {
			record.Details.Created = nowString
		}

		bugStyle = bugStyle + StringFromRecord(record) + "\n"

		// TODO: Batch these, don't send single requests
		if conf.Preview != "yes" {
			if "yes" == conf.OneCRLVerbose {
				fmt.Printf("record data is %s\n", StringFromRecord(record))
			}
		}
	}

	// Generate the data to attach to the bug
	bugStyleData := []byte(bugStyle)

	rTxt := new(RevocationsTxtData)
	for _, record := range existing.Data {
		rTxt.LoadRecord(record)
	}
	for _, record := range records.Data {
		rTxt.LoadRecord(record)
	}

	revocationsTxtString := rTxt.ToRevocationsTxtString()
	revocationsTxtData := []byte(revocationsTxtString)

	if shouldWrite {
		// Update Kinto records
		for _, record := range records.Data {
			update := new(OneCRLUpdate)
			update.Data = record

			// Upload the created entry to Kinto
			err := AddKintoObject(conf.KintoCollectionURL, update)
			if nil != err {
				panic(err)
			}
		}

		// Request review
		reviewJSON := "{\"data\": {\"status\": \"to-review\"}}"
		req, err := http.NewRequest("PATCH", conf.KintoCollectionURL, bytes.NewBuffer([]byte(reviewJSON)))

		if len(conf.KintoToken) > 0 {
			req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", conf.KintoToken))
		} else if len(conf.KintoUser) > 0 {
			req.SetBasicAuth(conf.KintoUser, conf.KintoPassword)
		}
		req.Header.Set("Content-Type", "application/json")

		client := &http.Client{}
		resp, err := client.Do(req)

		if "yes" == conf.OneCRLVerbose {
			fmt.Printf("requested review - status code is %d\n", resp.StatusCode)
		}

		defer resp.Body.Close()

		if err != nil {
			panic(err)
		}

		err = checkResponseStatus(resp, "There was a problem with requesting review")

		if nil != err {
			return err
		}

		// upload the created entries to bugzilla
		attachments := make([]bugs.Attachment, 2)
		encodedBugStyleData := base64.StdEncoding.EncodeToString(bugStyleData)
		attachments[0] = bugs.Attachment{}
		attachments[0].FileName = "BugData.txt"
		attachments[0].Summary = "Intermediates to be revoked"
		attachments[0].ContentType = "text/plain"
		attachments[0].Comment = "Revocations data for new records"
		attachments[0].ApiKey = conf.BugzillaAPIKey
		attachments[0].Data = encodedBugStyleData
		attachments[0].Flags = make([]bugs.AttachmentFlag, 0, 1)

		encodedRevocationsTxtData := base64.StdEncoding.EncodeToString(revocationsTxtData)
		attachments[1] = bugs.Attachment{}
		attachments[1].FileName = "revocations.txt"
		attachments[1].Summary = "existing and new revocations in the form of a revocations.txt file"
		attachments[1].ContentType = "text/plain"
		attachments[1].Comment = "Revocations data for new and existing records"
		attachments[1].ApiKey = conf.BugzillaAPIKey
		attachments[1].Data = encodedRevocationsTxtData
		attachments[1].Flags = make([]bugs.AttachmentFlag, 0, 1)

		// create flags for the reviewers
		for _, reviewer := range strings.Split(conf.BugzillaReviewers, ",") {
			trimmedReviewer := strings.Trim(reviewer, " ")
			if len(trimmedReviewer) > 0 {
				flag := bugs.AttachmentFlag{}
				flag.Name = "data-review"
				flag.Status = "?"
				flag.Requestee = trimmedReviewer
				flag.New = true
				attachments[0].Flags = append(attachments[0].Flags, flag)
				attachments[1].Flags = append(attachments[1].Flags, flag)
			}
		}

		if !conf.SkipBugzilla {
			if err = bugs.AttachToBug(bugNum, conf.BugzillaAPIKey, attachments, conf); err != nil {
				panic(err)
			}

			if err = bugs.AddCommentToBug(bugNum, conf, comment); err != nil {
				panic(err)
			}
		}
	} else {
		// If we aren't supposed to write, save locally
		bugDataFile, err := ioutil.TempFile("", "BugData.txt")
		if err != nil {
			panic(err)
		}
		if _, err = bugDataFile.Write(bugStyleData); err != nil {
			panic(err)
		}
		fmt.Printf("BugData.txt written to %s\n", bugDataFile.Name())

		revocationsFile, err := ioutil.TempFile("", "revocations.txt")
		if err != nil {
			panic(err)
		}
		if _, err = revocationsFile.Write(revocationsTxtData); err != nil {
			panic(err)
		}
		fmt.Printf("revocations.txt written to %s\n", revocationsFile.Name())
	}

	return nil
}