1
0
mirror of https://github.com/strongdm/comply synced 2025-12-16 19:24:01 +00:00

Compare commits

...

16 Commits

Author SHA1 Message Date
Justin McCarthy
0f68acae10 increment patch for release (via Makefile) 2018-05-29 16:35:06 -07:00
Justin McCarthy
19e100801a automated asset refresh (via Makefile) 2018-05-29 16:34:57 -07:00
Justin McCarthy
46aaf1c663 document model 2018-05-29 14:42:37 -07:00
Justin McCarthy
815e7e5f61 the data model for Narratives and Policies have converged, allowing both to be represented by a common Docume
nt struct.
2018-05-28 17:05:56 -05:00
Justin McCarthy
ff626a5ee2 pandoc must also include pdflatex 2018-05-28 16:46:35 -05:00
Justin McCarthy
1ec70a67d1 increment minor for release (via Makefile) 2018-05-23 17:16:55 -07:00
Justin McCarthy
096ad03ee1 automated asset refresh (via Makefile) 2018-05-23 17:16:47 -07:00
Justin McCarthy
5d67d60fd4 increment patch for release (via Makefile) 2018-05-23 17:04:43 -07:00
Justin McCarthy
8e3ebdc94a automated asset refresh (via Makefile) 2018-05-23 17:04:35 -07:00
Justin McCarthy
39fd371c4e spelled .envrc wrong 2018-05-23 17:04:03 -07:00
Justin McCarthy
1e5383eb01 env file to ignore 2018-05-23 16:53:07 -07:00
Justin McCarthy
49e950c3c0 If pandoc appears in the path, it will be preferred over Docker.
The pandoc version must be 2.2.1 or greater.

Defaults can be overridden by an optional "pandoc: pandoc"
or "pandoc: docker" in the comply.yml.
2018-05-23 16:48:35 -07:00
Justin McCarthy
ff350a2b89 Prepare pandoc upgrade (not pushed to docker hub yet) 2018-05-23 16:46:28 -07:00
Justin McCarthy
82baa57684 note pandoc dependency 2018-05-23 14:18:28 -07:00
Justin McCarthy
bb4200ff43 replace dockerMustExist with pandocMustExist dependency on build and serve commands 2018-05-23 14:15:39 -07:00
Justin McCarthy
1b807da10e Update AUTHORS.txt 2018-05-20 22:57:37 -07:00
20 changed files with 308 additions and 336 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
comply
output
dist
.envrc

View File

@@ -1,3 +1,4 @@
# Authors in alphabetical order:
Justin McCarthy <justin@strongdm.com>
Manisha Singh <manisha@strongdm.com>

View File

@@ -62,7 +62,6 @@ export-example:
docker:
cd build && docker build -t strongdm/pandoc .
docker tag jagregory/pandoc:latest strongdm/pandoc:latest
docker push strongdm/pandoc
cleanse:

View File

@@ -54,6 +54,10 @@ Join us in [Comply Users](https://join.slack.com/t/comply-users/shared_invite/en
## Dashboard
![screencast 2](sc-3.gif)
## Dependencies
Comply relies on [pandoc](https://pandoc.org/), which can be installed directly as an OS package or invoked via Docker.
## CLI
```

View File

@@ -1 +1 @@
1.1.26
1.2.1

View File

@@ -1,3 +1,28 @@
FROM scratch
FROM haskell:latest
MAINTAINER strongDM Comply <comply@strongdm.com>
# based on implementation by James Gregory <james@jagregory.com>
MAINTAINER Comply <comply@strongdm.com>
# install latex packages
RUN apt-get update -y \
&& apt-get install -y -o Acquire::Retries=10 --no-install-recommends \
texlive-latex-base \
texlive-xetex \
latex-xcolor \
texlive-latex-extra \
fontconfig \
unzip \
lmodern
# will ease up the update process
# updating this env variable will trigger the automatic build of the Docker image
ENV PANDOC_VERSION "2.2.1"
# install pandoc
RUN cabal update && cabal install pandoc-${PANDOC_VERSION}
WORKDIR /source
ENTRYPOINT ["/root/.cabal/bin/pandoc"]
CMD ["--help"]

View File

@@ -7,7 +7,10 @@ import (
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@@ -96,6 +99,66 @@ func ticketingMustBeConfigured(c *cli.Context) error {
return nil
}
func pandocMustExist(c *cli.Context) error {
eitherMustExistErr := fmt.Errorf("Please install either Docker or the pandoc package and re-run `%s`", c.Command.Name)
pandocExistErr := pandocBinaryMustExist(c)
dockerExistErr := dockerMustExist(c)
config.SetPandoc(pandocExistErr == nil, dockerExistErr == nil)
if pandocExistErr != nil && dockerExistErr != nil {
return eitherMustExistErr
}
return nil
}
func pandocBinaryMustExist(c *cli.Context) error {
cmd := exec.Command("pandoc", "-v")
outputRaw, err := cmd.Output()
if err != nil {
return errors.Wrap(err, "error calling pandoc")
}
output := strings.TrimSpace((string(outputRaw)))
versionErr := errors.New("cannot determine pandoc version")
if !strings.HasPrefix(output, "pandoc") {
return versionErr
}
re := regexp.MustCompile(`pandoc (\d+)\.(\d+)`)
result := re.FindStringSubmatch(output)
if len(result) != 3 {
return versionErr
}
major, err := strconv.Atoi(result[1])
if err != nil {
return versionErr
}
minor, err := strconv.Atoi(result[2])
if err != nil {
return versionErr
}
if major < 2 || minor < 1 {
return errors.New("pandoc 2.1 or greater required")
}
// pdflatex must also be present
cmd = exec.Command("pdflatex", "-v")
outputRaw, err = cmd.Output()
if err != nil {
return errors.Wrap(err, "error calling pdflatex")
}
if !strings.Contains(string(outputRaw), "TeX") {
return errors.New("pdflatex is required")
}
return nil
}
func dockerMustExist(c *cli.Context) error {
dockerErr := fmt.Errorf("Docker must be available in order to run `%s`", c.Command.Name)
@@ -146,12 +209,17 @@ func dockerMustExist(c *cli.Context) error {
}
func cleanContainers(c *cli.Context) error {
dockerErr := fmt.Errorf("Docker must be available in order to run `%s`", c.Command.Name)
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
return dockerErr
// no Docker? nothing to clean.
return nil
}
_, err = cli.Ping(ctx)
if err != nil {
// no Docker? nothing to clean.
return nil
}
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})

View File

@@ -11,7 +11,7 @@ var buildCommand = cli.Command{
ShortName: "b",
Usage: "generate a static website summarizing the compliance program",
Action: buildAction,
Before: beforeAll(dockerMustExist, cleanContainers),
Before: beforeAll(pandocMustExist, cleanContainers),
}
func buildAction(c *cli.Context) error {

View File

@@ -10,7 +10,7 @@ var serveCommand = cli.Command{
Name: "serve",
Usage: "live updating version of the build command",
Action: serveAction,
Before: beforeAll(dockerMustExist, cleanContainers),
Before: beforeAll(pandocMustExist, cleanContainers),
}
func serveAction(c *cli.Context) error {

View File

@@ -10,6 +10,15 @@ import (
var projectRoot string
var dockerAvailable, pandocAvailable bool
const (
// UseDocker invokes pandoc within Docker
UseDocker = "docker"
// UsePandoc invokes pandoc directly
UsePandoc = "pandoc"
)
// SetProjectRoot is used by the test suite.
func SetProjectRoot(dir string) {
projectRoot = dir
@@ -17,10 +26,32 @@ func SetProjectRoot(dir string) {
type Project struct {
Name string `yaml:"name"`
Pandoc string `yaml:"pandoc,omitempty"`
FilePrefix string `yaml:"filePrefix"`
Tickets map[string]interface{} `yaml:"tickets"`
}
// SetPandoc records pandoc availability during initialization
func SetPandoc(pandoc bool, docker bool) {
pandocAvailable = pandoc
dockerAvailable = docker
}
// WhichPandoc indicates which pandoc invocation path should be used
func WhichPandoc() string {
cfg := Config()
if cfg.Pandoc == UsePandoc {
return UsePandoc
}
if cfg.Pandoc == UseDocker {
return UseDocker
}
if pandocAvailable {
return UsePandoc
}
return UseDocker
}
// YAML is the parsed contents of ProjectRoot()/config.yml.
func YAML() map[interface{}]interface{} {
m := make(map[interface{}]interface{})

View File

@@ -2,7 +2,7 @@ package model
import "time"
type Policy struct {
type Document struct {
Name string `yaml:"name"`
Acronym string `yaml:"acronym"`

View File

@@ -91,8 +91,8 @@ func ReadStandards() ([]*Standard, error) {
}
// ReadNarratives loads narrative descriptions from the filesystem.
func ReadNarratives() ([]*Narrative, error) {
var narratives []*Narrative
func ReadNarratives() ([]*Document, error) {
var narratives []*Document
files, err := path.Narratives()
if err != nil {
@@ -100,7 +100,7 @@ func ReadNarratives() ([]*Narrative, error) {
}
for _, f := range files {
n := &Narrative{}
n := &Document{}
mdmd := loadMDMD(f.FullPath)
err = yaml.Unmarshal([]byte(mdmd.yaml), &n)
if err != nil {
@@ -141,8 +141,8 @@ func ReadProcedures() ([]*Procedure, error) {
}
// ReadPolicies loads policy documents from the filesystem.
func ReadPolicies() ([]*Policy, error) {
var policies []*Policy
func ReadPolicies() ([]*Document, error) {
var policies []*Document
files, err := path.Policies()
if err != nil {
@@ -150,7 +150,7 @@ func ReadPolicies() ([]*Policy, error) {
}
for _, f := range files {
p := &Policy{}
p := &Document{}
mdmd := loadMDMD(f.FullPath)
err = yaml.Unmarshal([]byte(mdmd.yaml), &p)
if err != nil {

View File

@@ -2,8 +2,8 @@ package model
type Data struct {
Standards []*Standard
Narratives []*Narrative
Policies []*Policy
Narratives []*Document
Policies []*Document
Procedures []*Procedure
Tickets []*Ticket
Audits []*Audit

View File

@@ -1,15 +0,0 @@
package model
import "time"
type Narrative struct {
Name string `yaml:"name"`
Acronym string `yaml:"acronym"`
Revisions []Revision `yaml:"majorRevisions"`
Satisfies Satisfaction `yaml:"satisfies"`
FullPath string
OutputFilename string
ModifiedAt time.Time
Body string
}

View File

@@ -32,8 +32,8 @@ type renderData struct {
Name string
Project *project
Stats *stats
Narratives []*model.Narrative
Policies []*model.Policy
Narratives []*model.Document
Policies []*model.Document
Procedures []*model.Procedure
Standards []*model.Standard
Tickets []*model.Ticket

View File

@@ -2,7 +2,6 @@ package render
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
@@ -12,89 +11,32 @@ import (
"text/template"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/strongdm/comply/internal/config"
"github.com/strongdm/comply/internal/model"
)
// TODO: refactor and eliminate duplication among narrative, policy renderers
func renderPolicyToDisk(wg *sync.WaitGroup, errOutputCh chan error, data *renderData, policy *model.Policy, live bool) {
func renderToFilesystem(wg *sync.WaitGroup, errOutputCh chan error, data *renderData, doc *model.Document, live bool) {
// only files that have been touched
if !isNewer(policy.FullPath, policy.ModifiedAt) {
if !isNewer(doc.FullPath, doc.ModifiedAt) {
return
}
recordModified(policy.FullPath, policy.ModifiedAt)
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to read Docker environment")
return
}
pwd, err := os.Getwd()
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to get workding directory")
return
}
hc := &container.HostConfig{
Binds: []string{pwd + ":/source"},
}
recordModified(doc.FullPath, doc.ModifiedAt)
wg.Add(1)
go func(p *model.Policy) {
go func(p *model.Document) {
defer wg.Done()
outputFilename := p.OutputFilename
// save preprocessed markdown
err = preprocessPolicy(data, p, filepath.Join(".", "output", outputFilename+".md"))
err := preprocessDoc(data, p, filepath.Join(".", "output", outputFilename+".md"))
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to preprocess")
return
}
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: "strongdm/pandoc",
Cmd: []string{"--smart", "--toc", "-N", "--template=/source/templates/default.latex", "-o",
fmt.Sprintf("/source/output/%s", outputFilename),
fmt.Sprintf("/source/output/%s.md", outputFilename),
},
}, hc, nil, "")
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to create Docker container")
return
}
defer func() {
timeout := 2 * time.Second
cli.ContainerStop(ctx, resp.ID, &timeout)
err := cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to remove container")
return
}
}()
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
errOutputCh <- errors.Wrap(err, "unable to start Docker container")
return
}
_, err = cli.ContainerWait(ctx, resp.ID)
if err != nil {
errOutputCh <- errors.Wrap(err, "error awaiting Docker container")
return
}
_, err = cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
if err != nil {
errOutputCh <- errors.Wrap(err, "error reading Docker container logs")
return
}
pandoc(outputFilename, errOutputCh)
// remove preprocessed markdown
err = os.Remove(filepath.Join(".", "output", outputFilename+".md"))
@@ -108,10 +50,10 @@ func renderPolicyToDisk(wg *sync.WaitGroup, errOutputCh chan error, data *render
rel = p.FullPath
}
fmt.Printf("%s -> %s\n", rel, filepath.Join("output", p.OutputFilename))
}(policy)
}(doc)
}
func preprocessPolicy(data *renderData, pol *model.Policy, fullPath string) error {
func preprocessDoc(data *renderData, pol *model.Document, fullPath string) error {
cfg := config.Config()
var w bytes.Buffer

View File

@@ -1,184 +0,0 @@
package render
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"text/template"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/strongdm/comply/internal/config"
"github.com/strongdm/comply/internal/model"
)
// TODO: refactor and eliminate duplication among narrative, policy renderers
func renderNarrativeToDisk(wg *sync.WaitGroup, errOutputCh chan error, data *renderData, narrative *model.Narrative, live bool) {
// only files that have been touched
if !isNewer(narrative.FullPath, narrative.ModifiedAt) {
return
}
recordModified(narrative.FullPath, narrative.ModifiedAt)
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to read Docker environment")
return
}
pwd, err := os.Getwd()
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to get workding directory")
return
}
hc := &container.HostConfig{
Binds: []string{pwd + ":/source"},
}
wg.Add(1)
go func(p *model.Narrative) {
defer wg.Done()
outputFilename := p.OutputFilename
// save preprocessed markdown
err = preprocessNarrative(data, p, filepath.Join(".", "output", outputFilename+".md"))
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to preprocess")
return
}
cmd := []string{"--smart", "--toc", "-N", "--template=/source/templates/default.latex", "-o",
fmt.Sprintf("/source/output/%s", outputFilename),
fmt.Sprintf("/source/output/%s.md", outputFilename)}
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: "strongdm/pandoc",
Cmd: cmd},
hc, nil, "")
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to create Docker container")
return
}
defer func() {
timeout := 2 * time.Second
cli.ContainerStop(ctx, resp.ID, &timeout)
err := cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to remove container")
return
}
}()
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
errOutputCh <- errors.Wrap(err, "unable to start Docker container")
return
}
_, err = cli.ContainerWait(ctx, resp.ID)
if err != nil {
errOutputCh <- errors.Wrap(err, "error awaiting Docker container")
return
}
_, err = cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
if err != nil {
errOutputCh <- errors.Wrap(err, "error reading Docker container logs")
return
}
// remove preprocessed markdown
err = os.Remove(filepath.Join(".", "output", outputFilename+".md"))
if err != nil {
errOutputCh <- err
return
}
rel, err := filepath.Rel(config.ProjectRoot(), p.FullPath)
if err != nil {
rel = p.FullPath
}
fmt.Printf("%s -> %s\n", rel, filepath.Join("output", p.OutputFilename))
}(narrative)
}
func preprocessNarrative(data *renderData, pol *model.Narrative, fullPath string) error {
cfg := config.Config()
var w bytes.Buffer
bodyTemplate, err := template.New("body").Parse(pol.Body)
if err != nil {
w.WriteString(fmt.Sprintf("# Error processing template:\n\n%s\n", err.Error()))
} else {
bodyTemplate.Execute(&w, data)
}
body := w.String()
revisionTable := ""
satisfiesTable := ""
// ||Date|Comment|
// |---+------|
// | 4 Jan 2018 | Initial Version |
// Table: Document history
if len(pol.Satisfies) > 0 {
rows := ""
for standard, keys := range pol.Satisfies {
rows += fmt.Sprintf("| %s | %s |\n", standard, strings.Join(keys, ", "))
}
satisfiesTable = fmt.Sprintf("|Standard|Controls Satisfied|\n|-------+--------------------------------------------|\n%s\nTable: Control satisfaction\n", rows)
}
if len(pol.Revisions) > 0 {
rows := ""
for _, rev := range pol.Revisions {
rows += fmt.Sprintf("| %s | %s |\n", rev.Date, rev.Comment)
}
revisionTable = fmt.Sprintf("|Date|Comment|\n|---+--------------------------------------------|\n%s\nTable: Document history\n", rows)
}
doc := fmt.Sprintf(`%% %s
%% %s
%% %s
---
header-includes: yes
head-content: "%s"
foot-content: "%s confidential %d"
---
%s
%s
\newpage
%s`,
pol.Name,
cfg.Name,
fmt.Sprintf("%s %d", pol.ModifiedAt.Month().String(), pol.ModifiedAt.Year()),
pol.Name,
cfg.Name,
time.Now().Year(),
satisfiesTable,
revisionTable,
body,
)
err = ioutil.WriteFile(fullPath, []byte(doc), os.FileMode(0644))
if err != nil {
return errors.Wrap(err, "unable to write preprocessed narrative to disk")
}
return nil
}

100
internal/render/pandoc.go Normal file
View File

@@ -0,0 +1,100 @@
package render
import (
"context"
"fmt"
"os"
"os/exec"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/strongdm/comply/internal/config"
)
func pandoc(outputFilename string, errOutputCh chan error) {
if config.WhichPandoc() == config.UsePandoc {
err := pandocPandoc(outputFilename)
if err != nil {
errOutputCh <- err
}
} else {
dockerPandoc(outputFilename, errOutputCh)
}
}
func dockerPandoc(outputFilename string, errOutputCh chan error) {
// TODO: switch to new args once docker image is updated
// cmd21 := []string{"-f", "markdown+smart", "--toc", "-N", "--template", "templates/default.latex", "-o", fmt.Sprintf("output/%s", outputFilename), fmt.Sprintf("output/%s.md", outputFilename)}
cmd19 := []string{"--smart", "--toc", "-N", "--template=/source/templates/default.latex", "-o",
fmt.Sprintf("/source/output/%s", outputFilename),
fmt.Sprintf("/source/output/%s.md", outputFilename)}
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to read Docker environment")
return
}
pwd, err := os.Getwd()
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to get workding directory")
return
}
hc := &container.HostConfig{
Binds: []string{pwd + ":/source"},
}
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: "strongdm/pandoc",
Cmd: cmd19},
hc, nil, "")
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to create Docker container")
return
}
defer func() {
timeout := 2 * time.Second
cli.ContainerStop(ctx, resp.ID, &timeout)
err := cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
if err != nil {
errOutputCh <- errors.Wrap(err, "unable to remove container")
return
}
}()
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
errOutputCh <- errors.Wrap(err, "unable to start Docker container")
return
}
_, err = cli.ContainerWait(ctx, resp.ID)
if err != nil {
errOutputCh <- errors.Wrap(err, "error awaiting Docker container")
return
}
_, err = cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})
if err != nil {
errOutputCh <- errors.Wrap(err, "error reading Docker container logs")
return
}
}
// 🐼
func pandocPandoc(outputFilename string) error {
// -f markdown+smart --toc -N --template=templates/default.latex -o output/%s output/%s.md
cmd := exec.Command("pandoc", "-f", "markdown+smart", "--toc", "-N", "--template", "templates/default.latex", "-o", fmt.Sprintf("output/%s", outputFilename), fmt.Sprintf("output/%s.md", outputFilename))
outputRaw, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(string(outputRaw))
return errors.Wrap(err, "error calling pandoc")
}
return nil
}

View File

@@ -25,7 +25,7 @@ func pdf(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
return
}
for _, policy := range policies {
renderPolicyToDisk(&pdfWG, errOutputCh, data, policy, live)
renderToFilesystem(&pdfWG, errOutputCh, data, policy, live)
}
narratives, err := model.ReadNarratives()
@@ -35,7 +35,7 @@ func pdf(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
}
for _, narrative := range narratives {
renderNarrativeToDisk(&pdfWG, errOutputCh, data, narrative, live)
renderToFilesystem(&pdfWG, errOutputCh, data, narrative, live)
}
pdfWG.Wait()

View File

@@ -137,7 +137,7 @@ func complyBlankReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-blank/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-blank/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -157,7 +157,7 @@ func complyBlankTodoMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-blank/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-blank/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -277,7 +277,7 @@ func complyBlankTemplatesDefaultLatex() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-blank/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-blank/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -297,7 +297,7 @@ func complyBlankTemplatesIndexAce() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-blank/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-blank/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -317,7 +317,7 @@ func complySoc2ReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/README.md", size: 1965, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -337,7 +337,7 @@ func complySoc2TodoMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/TODO.md", size: 1429, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -357,7 +357,7 @@ func complySoc2NarrativesReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/narratives/README.md", size: 96, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/narratives/README.md", size: 96, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -377,7 +377,7 @@ func complySoc2NarrativesControlMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/narratives/control.md", size: 387, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/narratives/control.md", size: 387, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -397,7 +397,7 @@ func complySoc2NarrativesOrganizationalMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/narratives/organizational.md", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/narratives/organizational.md", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -417,7 +417,7 @@ func complySoc2NarrativesProductsMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/narratives/products.md", size: 232, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/narratives/products.md", size: 232, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -437,7 +437,7 @@ func complySoc2NarrativesSecurityMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/narratives/security.md", size: 327, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/narratives/security.md", size: 327, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -457,7 +457,7 @@ func complySoc2NarrativesSystemMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/narratives/system.md", size: 257, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/narratives/system.md", size: 257, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -477,7 +477,7 @@ func complySoc2PoliciesReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/README.md", size: 71, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/README.md", size: 71, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -497,7 +497,7 @@ func complySoc2PoliciesAccessMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/access.md", size: 2175, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/access.md", size: 2175, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -517,7 +517,7 @@ func complySoc2PoliciesApplicationMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/application.md", size: 8377, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/application.md", size: 8377, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -537,7 +537,7 @@ func complySoc2PoliciesAvailabilityMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/availability.md", size: 7019, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/availability.md", size: 7019, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -557,7 +557,7 @@ func complySoc2PoliciesChangeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/change.md", size: 2793, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/change.md", size: 2793, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -577,7 +577,7 @@ func complySoc2PoliciesClassificationMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/classification.md", size: 14376, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/classification.md", size: 14376, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -597,7 +597,7 @@ func complySoc2PoliciesConductMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/conduct.md", size: 4492, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/conduct.md", size: 4492, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -617,7 +617,7 @@ func complySoc2PoliciesConfidentialityMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/confidentiality.md", size: 3653, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/confidentiality.md", size: 3653, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -637,7 +637,7 @@ func complySoc2PoliciesContinuityMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/continuity.md", size: 5043, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/continuity.md", size: 5043, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -657,7 +657,7 @@ func complySoc2PoliciesCyberMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/cyber.md", size: 4805, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/cyber.md", size: 4805, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -677,7 +677,7 @@ func complySoc2PoliciesDatacenterMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/datacenter.md", size: 3014, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/datacenter.md", size: 3014, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -697,7 +697,7 @@ func complySoc2PoliciesDevelopmentMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/development.md", size: 8933, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/development.md", size: 8933, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -717,7 +717,7 @@ func complySoc2PoliciesDisasterMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/disaster.md", size: 10315, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/disaster.md", size: 10315, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -737,7 +737,7 @@ func complySoc2PoliciesEncryptionMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/encryption.md", size: 5381, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/encryption.md", size: 5381, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -757,7 +757,7 @@ func complySoc2PoliciesIncidentMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/incident.md", size: 8552, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/incident.md", size: 8552, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -777,7 +777,7 @@ func complySoc2PoliciesInformationMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/information.md", size: 5359, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/information.md", size: 5359, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -797,7 +797,7 @@ func complySoc2PoliciesLogMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/log.md", size: 4307, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/log.md", size: 4307, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -817,7 +817,7 @@ func complySoc2PoliciesMediaMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/media.md", size: 8819, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/media.md", size: 8819, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -837,7 +837,7 @@ func complySoc2PoliciesOfficeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/office.md", size: 3927, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/office.md", size: 3927, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -857,7 +857,7 @@ func complySoc2PoliciesPasswordMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/password.md", size: 1796, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/password.md", size: 1796, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -877,7 +877,7 @@ func complySoc2PoliciesPolicyMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/policy.md", size: 892, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/policy.md", size: 892, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -897,7 +897,7 @@ func complySoc2PoliciesPrivacyMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/privacy.md", size: 346, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/privacy.md", size: 346, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -917,7 +917,7 @@ func complySoc2PoliciesProcessingMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/processing.md", size: 210, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/processing.md", size: 210, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -937,7 +937,7 @@ func complySoc2PoliciesRemoteMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/remote.md", size: 4119, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/remote.md", size: 4119, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -957,7 +957,7 @@ func complySoc2PoliciesRetentionMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/retention.md", size: 6811, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/retention.md", size: 6811, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -977,7 +977,7 @@ func complySoc2PoliciesRiskMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/risk.md", size: 10486, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/risk.md", size: 10486, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -997,7 +997,7 @@ func complySoc2PoliciesVendorMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/vendor.md", size: 3139, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/vendor.md", size: 3139, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1017,7 +1017,7 @@ func complySoc2PoliciesWorkstationMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/policies/workstation.md", size: 1791, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/policies/workstation.md", size: 1791, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1037,7 +1037,7 @@ func complySoc2ProceduresReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/procedures/README.md", size: 92, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/procedures/README.md", size: 92, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1057,7 +1057,7 @@ func complySoc2ProceduresOffboardingMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/procedures/offboarding.md", size: 358, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/procedures/offboarding.md", size: 358, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1077,7 +1077,7 @@ func complySoc2ProceduresOnboardingMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/procedures/onboarding.md", size: 495, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/procedures/onboarding.md", size: 495, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1097,7 +1097,7 @@ func complySoc2ProceduresPatchMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/procedures/patch.md", size: 380, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/procedures/patch.md", size: 380, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1117,7 +1117,7 @@ func complySoc2ProceduresWorkstationMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/procedures/workstation.md", size: 1081, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/procedures/workstation.md", size: 1081, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1137,7 +1137,7 @@ func complySoc2StandardsReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/standards/README.md", size: 282, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/standards/README.md", size: 282, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1157,7 +1157,7 @@ func complySoc2StandardsTsc2017Yml() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/standards/TSC-2017.yml", size: 16305, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/standards/TSC-2017.yml", size: 16305, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1177,7 +1177,7 @@ func complySoc2TemplatesDefaultLatex() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/templates/default.latex", size: 7649, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -1197,7 +1197,7 @@ func complySoc2TemplatesIndexAce() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "comply-soc2/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1526689985, 0)}
info := bindataFileInfo{name: "comply-soc2/templates/index.ace", size: 7596, mode: os.FileMode(420), modTime: time.Unix(1527636896, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}