mirror of
https://github.com/strongdm/comply
synced 2025-12-18 12:13:51 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f68acae10 | ||
|
|
19e100801a | ||
|
|
46aaf1c663 | ||
|
|
815e7e5f61 | ||
|
|
ff626a5ee2 | ||
|
|
1ec70a67d1 | ||
|
|
096ad03ee1 | ||
|
|
5d67d60fd4 | ||
|
|
8e3ebdc94a | ||
|
|
39fd371c4e | ||
|
|
1e5383eb01 | ||
|
|
49e950c3c0 | ||
|
|
ff350a2b89 | ||
|
|
82baa57684 | ||
|
|
bb4200ff43 | ||
|
|
1b807da10e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
comply
|
comply
|
||||||
output
|
output
|
||||||
dist
|
dist
|
||||||
|
.envrc
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
# Authors in alphabetical order:
|
# Authors in alphabetical order:
|
||||||
|
|
||||||
Justin McCarthy <justin@strongdm.com>
|
Justin McCarthy <justin@strongdm.com>
|
||||||
|
Manisha Singh <manisha@strongdm.com>
|
||||||
|
|||||||
1
Makefile
1
Makefile
@@ -62,7 +62,6 @@ export-example:
|
|||||||
|
|
||||||
docker:
|
docker:
|
||||||
cd build && docker build -t strongdm/pandoc .
|
cd build && docker build -t strongdm/pandoc .
|
||||||
docker tag jagregory/pandoc:latest strongdm/pandoc:latest
|
|
||||||
docker push strongdm/pandoc
|
docker push strongdm/pandoc
|
||||||
|
|
||||||
cleanse:
|
cleanse:
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ Join us in [Comply Users](https://join.slack.com/t/comply-users/shared_invite/en
|
|||||||
## Dashboard
|
## Dashboard
|
||||||

|

|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Comply relies on [pandoc](https://pandoc.org/), which can be installed directly as an OS package or invoked via Docker.
|
||||||
|
|
||||||
## CLI
|
## CLI
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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"]
|
||||||
@@ -7,7 +7,10 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -96,6 +99,66 @@ func ticketingMustBeConfigured(c *cli.Context) error {
|
|||||||
return nil
|
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 {
|
func dockerMustExist(c *cli.Context) error {
|
||||||
dockerErr := fmt.Errorf("Docker must be available in order to run `%s`", c.Command.Name)
|
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 {
|
func cleanContainers(c *cli.Context) error {
|
||||||
dockerErr := fmt.Errorf("Docker must be available in order to run `%s`", c.Command.Name)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
cli, err := client.NewEnvClient()
|
cli, err := client.NewEnvClient()
|
||||||
if err != nil {
|
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})
|
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ var buildCommand = cli.Command{
|
|||||||
ShortName: "b",
|
ShortName: "b",
|
||||||
Usage: "generate a static website summarizing the compliance program",
|
Usage: "generate a static website summarizing the compliance program",
|
||||||
Action: buildAction,
|
Action: buildAction,
|
||||||
Before: beforeAll(dockerMustExist, cleanContainers),
|
Before: beforeAll(pandocMustExist, cleanContainers),
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildAction(c *cli.Context) error {
|
func buildAction(c *cli.Context) error {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ var serveCommand = cli.Command{
|
|||||||
Name: "serve",
|
Name: "serve",
|
||||||
Usage: "live updating version of the build command",
|
Usage: "live updating version of the build command",
|
||||||
Action: serveAction,
|
Action: serveAction,
|
||||||
Before: beforeAll(dockerMustExist, cleanContainers),
|
Before: beforeAll(pandocMustExist, cleanContainers),
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveAction(c *cli.Context) error {
|
func serveAction(c *cli.Context) error {
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ import (
|
|||||||
|
|
||||||
var projectRoot string
|
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.
|
// SetProjectRoot is used by the test suite.
|
||||||
func SetProjectRoot(dir string) {
|
func SetProjectRoot(dir string) {
|
||||||
projectRoot = dir
|
projectRoot = dir
|
||||||
@@ -17,10 +26,32 @@ func SetProjectRoot(dir string) {
|
|||||||
|
|
||||||
type Project struct {
|
type Project struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
|
Pandoc string `yaml:"pandoc,omitempty"`
|
||||||
FilePrefix string `yaml:"filePrefix"`
|
FilePrefix string `yaml:"filePrefix"`
|
||||||
Tickets map[string]interface{} `yaml:"tickets"`
|
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.
|
// YAML is the parsed contents of ProjectRoot()/config.yml.
|
||||||
func YAML() map[interface{}]interface{} {
|
func YAML() map[interface{}]interface{} {
|
||||||
m := make(map[interface{}]interface{})
|
m := make(map[interface{}]interface{})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package model
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Policy struct {
|
type Document struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Acronym string `yaml:"acronym"`
|
Acronym string `yaml:"acronym"`
|
||||||
|
|
||||||
@@ -91,8 +91,8 @@ func ReadStandards() ([]*Standard, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadNarratives loads narrative descriptions from the filesystem.
|
// ReadNarratives loads narrative descriptions from the filesystem.
|
||||||
func ReadNarratives() ([]*Narrative, error) {
|
func ReadNarratives() ([]*Document, error) {
|
||||||
var narratives []*Narrative
|
var narratives []*Document
|
||||||
|
|
||||||
files, err := path.Narratives()
|
files, err := path.Narratives()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -100,7 +100,7 @@ func ReadNarratives() ([]*Narrative, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
n := &Narrative{}
|
n := &Document{}
|
||||||
mdmd := loadMDMD(f.FullPath)
|
mdmd := loadMDMD(f.FullPath)
|
||||||
err = yaml.Unmarshal([]byte(mdmd.yaml), &n)
|
err = yaml.Unmarshal([]byte(mdmd.yaml), &n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -141,8 +141,8 @@ func ReadProcedures() ([]*Procedure, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadPolicies loads policy documents from the filesystem.
|
// ReadPolicies loads policy documents from the filesystem.
|
||||||
func ReadPolicies() ([]*Policy, error) {
|
func ReadPolicies() ([]*Document, error) {
|
||||||
var policies []*Policy
|
var policies []*Document
|
||||||
|
|
||||||
files, err := path.Policies()
|
files, err := path.Policies()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,7 +150,7 @@ func ReadPolicies() ([]*Policy, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
p := &Policy{}
|
p := &Document{}
|
||||||
mdmd := loadMDMD(f.FullPath)
|
mdmd := loadMDMD(f.FullPath)
|
||||||
err = yaml.Unmarshal([]byte(mdmd.yaml), &p)
|
err = yaml.Unmarshal([]byte(mdmd.yaml), &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package model
|
|||||||
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
Standards []*Standard
|
Standards []*Standard
|
||||||
Narratives []*Narrative
|
Narratives []*Document
|
||||||
Policies []*Policy
|
Policies []*Document
|
||||||
Procedures []*Procedure
|
Procedures []*Procedure
|
||||||
Tickets []*Ticket
|
Tickets []*Ticket
|
||||||
Audits []*Audit
|
Audits []*Audit
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -32,8 +32,8 @@ type renderData struct {
|
|||||||
Name string
|
Name string
|
||||||
Project *project
|
Project *project
|
||||||
Stats *stats
|
Stats *stats
|
||||||
Narratives []*model.Narrative
|
Narratives []*model.Document
|
||||||
Policies []*model.Policy
|
Policies []*model.Document
|
||||||
Procedures []*model.Procedure
|
Procedures []*model.Procedure
|
||||||
Standards []*model.Standard
|
Standards []*model.Standard
|
||||||
Tickets []*model.Ticket
|
Tickets []*model.Ticket
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package render
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@@ -12,89 +11,32 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"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/pkg/errors"
|
||||||
"github.com/strongdm/comply/internal/config"
|
"github.com/strongdm/comply/internal/config"
|
||||||
"github.com/strongdm/comply/internal/model"
|
"github.com/strongdm/comply/internal/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: refactor and eliminate duplication among narrative, policy renderers
|
// 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
|
// only files that have been touched
|
||||||
if !isNewer(policy.FullPath, policy.ModifiedAt) {
|
if !isNewer(doc.FullPath, doc.ModifiedAt) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
recordModified(policy.FullPath, policy.ModifiedAt)
|
recordModified(doc.FullPath, doc.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)
|
wg.Add(1)
|
||||||
go func(p *model.Policy) {
|
go func(p *model.Document) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
outputFilename := p.OutputFilename
|
outputFilename := p.OutputFilename
|
||||||
// save preprocessed markdown
|
// save preprocessed markdown
|
||||||
err = preprocessPolicy(data, p, filepath.Join(".", "output", outputFilename+".md"))
|
err := preprocessDoc(data, p, filepath.Join(".", "output", outputFilename+".md"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errOutputCh <- errors.Wrap(err, "unable to preprocess")
|
errOutputCh <- errors.Wrap(err, "unable to preprocess")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := cli.ContainerCreate(ctx, &container.Config{
|
pandoc(outputFilename, errOutputCh)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove preprocessed markdown
|
// remove preprocessed markdown
|
||||||
err = os.Remove(filepath.Join(".", "output", outputFilename+".md"))
|
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
|
rel = p.FullPath
|
||||||
}
|
}
|
||||||
fmt.Printf("%s -> %s\n", rel, filepath.Join("output", p.OutputFilename))
|
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()
|
cfg := config.Config()
|
||||||
|
|
||||||
var w bytes.Buffer
|
var w bytes.Buffer
|
||||||
@@ -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
100
internal/render/pandoc.go
Normal 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
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ func pdf(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, policy := range policies {
|
for _, policy := range policies {
|
||||||
renderPolicyToDisk(&pdfWG, errOutputCh, data, policy, live)
|
renderToFilesystem(&pdfWG, errOutputCh, data, policy, live)
|
||||||
}
|
}
|
||||||
|
|
||||||
narratives, err := model.ReadNarratives()
|
narratives, err := model.ReadNarratives()
|
||||||
@@ -35,7 +35,7 @@ func pdf(output string, live bool, errCh chan error, wg *sync.WaitGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, narrative := range narratives {
|
for _, narrative := range narratives {
|
||||||
renderNarrativeToDisk(&pdfWG, errOutputCh, data, narrative, live)
|
renderToFilesystem(&pdfWG, errOutputCh, data, narrative, live)
|
||||||
}
|
}
|
||||||
|
|
||||||
pdfWG.Wait()
|
pdfWG.Wait()
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ func complyBlankReadmeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ func complyBlankTodoMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -277,7 +277,7 @@ func complyBlankTemplatesDefaultLatex() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -297,7 +297,7 @@ func complyBlankTemplatesIndexAce() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -317,7 +317,7 @@ func complySoc2ReadmeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ func complySoc2TodoMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -357,7 +357,7 @@ func complySoc2NarrativesReadmeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ func complySoc2NarrativesControlMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -397,7 +397,7 @@ func complySoc2NarrativesOrganizationalMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ func complySoc2NarrativesProductsMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -437,7 +437,7 @@ func complySoc2NarrativesSecurityMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -457,7 +457,7 @@ func complySoc2NarrativesSystemMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -477,7 +477,7 @@ func complySoc2PoliciesReadmeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -497,7 +497,7 @@ func complySoc2PoliciesAccessMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -517,7 +517,7 @@ func complySoc2PoliciesApplicationMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -537,7 +537,7 @@ func complySoc2PoliciesAvailabilityMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -557,7 +557,7 @@ func complySoc2PoliciesChangeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -577,7 +577,7 @@ func complySoc2PoliciesClassificationMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -597,7 +597,7 @@ func complySoc2PoliciesConductMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -617,7 +617,7 @@ func complySoc2PoliciesConfidentialityMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -637,7 +637,7 @@ func complySoc2PoliciesContinuityMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -657,7 +657,7 @@ func complySoc2PoliciesCyberMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -677,7 +677,7 @@ func complySoc2PoliciesDatacenterMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -697,7 +697,7 @@ func complySoc2PoliciesDevelopmentMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -717,7 +717,7 @@ func complySoc2PoliciesDisasterMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -737,7 +737,7 @@ func complySoc2PoliciesEncryptionMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -757,7 +757,7 @@ func complySoc2PoliciesIncidentMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -777,7 +777,7 @@ func complySoc2PoliciesInformationMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -797,7 +797,7 @@ func complySoc2PoliciesLogMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -817,7 +817,7 @@ func complySoc2PoliciesMediaMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -837,7 +837,7 @@ func complySoc2PoliciesOfficeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -857,7 +857,7 @@ func complySoc2PoliciesPasswordMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -877,7 +877,7 @@ func complySoc2PoliciesPolicyMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -897,7 +897,7 @@ func complySoc2PoliciesPrivacyMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -917,7 +917,7 @@ func complySoc2PoliciesProcessingMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -937,7 +937,7 @@ func complySoc2PoliciesRemoteMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -957,7 +957,7 @@ func complySoc2PoliciesRetentionMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -977,7 +977,7 @@ func complySoc2PoliciesRiskMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -997,7 +997,7 @@ func complySoc2PoliciesVendorMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1017,7 +1017,7 @@ func complySoc2PoliciesWorkstationMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1037,7 +1037,7 @@ func complySoc2ProceduresReadmeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1057,7 +1057,7 @@ func complySoc2ProceduresOffboardingMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1077,7 +1077,7 @@ func complySoc2ProceduresOnboardingMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1097,7 +1097,7 @@ func complySoc2ProceduresPatchMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1117,7 +1117,7 @@ func complySoc2ProceduresWorkstationMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1137,7 +1137,7 @@ func complySoc2StandardsReadmeMd() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1157,7 +1157,7 @@ func complySoc2StandardsTsc2017Yml() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1177,7 +1177,7 @@ func complySoc2TemplatesDefaultLatex() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
@@ -1197,7 +1197,7 @@ func complySoc2TemplatesIndexAce() (*asset, error) {
|
|||||||
return nil, err
|
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}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user