Skip to content

Commit 8664643

Browse files
committed
fix validation and update for v2 schema
Signed-off-by: Sylwester Piskozub <sylwesterpiskozub@gmail.com>
1 parent 7522f2a commit 8664643

7 files changed

Lines changed: 200 additions & 174 deletions

File tree

app/cli/cmd/workflow_contract_create.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ func newWorkflowContractCreateCmd() *cobra.Command {
4343
}
4444

4545
cmd.Flags().StringVar(&name, "name", "", "contract name")
46-
err := cmd.MarkFlagRequired("name")
47-
cobra.CheckErr(err)
48-
4946
cmd.Flags().StringVarP(&contractPath, "contract", "f", "", "path or URL to the contract schema")
5047
cmd.Flags().StringVar(&description, "description", "", "description of the contract")
5148
cmd.Flags().StringVar(&projectName, "project", "", "project name used to scope the contract, if not set the contract will be created in the organization")

app/cli/cmd/workflow_contract_update.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ func newWorkflowContractUpdateCmd() *cobra.Command {
5353
}
5454

5555
cmd.Flags().StringVar(&name, "name", "", "contract name")
56-
err := cmd.MarkFlagRequired("name")
57-
cobra.CheckErr(err)
58-
5956
cmd.Flags().StringVarP(&contractPath, "contract", "f", "", "path or URL to the contract schema")
60-
61-
cobra.CheckErr(err)
6257
cmd.Flags().StringVar(&description, "description", "", "description of the contract")
6358

6459
return cmd

app/controlplane/api/controlplane/v1/workflow_contract.pb.go

Lines changed: 162 additions & 142 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/api/controlplane/v1/workflow_contract.proto

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,7 @@ message WorkflowContractServiceListResponse {
3838
}
3939

4040
message WorkflowContractServiceCreateRequest {
41-
string name = 1 [(buf.validate.field) = {
42-
cel: {
43-
message: "must contain only lowercase letters, numbers, and hyphens."
44-
expression: "this.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')"
45-
id: "name.dns-1123"
46-
}
47-
}];
41+
string name = 1;
4842

4943
// Raw representation of the contract in json, yaml or cue
5044
bytes raw_contract = 4;
@@ -53,25 +47,41 @@ message WorkflowContractServiceCreateRequest {
5347

5448
// You might need to specify a project reference if you want/need to create a contract scoped to a project
5549
IdentityReference project_reference = 5;
50+
51+
option (buf.validate.message).cel = {
52+
id: "name.dns-1122"
53+
message: "must contain only lowercase letters, numbers, and hyphens."
54+
expression: "this.name == '' || this.name.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')"
55+
};
56+
option (buf.validate.message).cel = {
57+
id: "name_required_without_contract"
58+
message: "name is required when raw_contract is not provided"
59+
expression: "this.name != '' || size(this.raw_contract) > 0"
60+
};
5661
}
5762

5863
message WorkflowContractServiceCreateResponse {
5964
WorkflowContractItem result = 1;
6065
}
6166

6267
message WorkflowContractServiceUpdateRequest {
63-
string name = 1 [(buf.validate.field) = {
64-
cel: {
65-
message: "must contain only lowercase letters, numbers, and hyphens."
66-
expression: "this.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')"
67-
id: "name.dns-1123"
68-
}
69-
}];
68+
string name = 1;
7069

7170
// Raw representation of the contract in json, yaml or cue
7271
bytes raw_contract = 5;
7372

7473
optional string description = 4;
74+
75+
option (buf.validate.message).cel = {
76+
id: "name.dns-1122"
77+
message: "must contain only lowercase letters, numbers, and hyphens."
78+
expression: "this.name == '' || this.name.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')"
79+
};
80+
option (buf.validate.message).cel = {
81+
id: "name_required_without_contract"
82+
message: "name is required when raw_contract is not provided"
83+
expression: "this.name != '' || size(this.raw_contract) > 0"
84+
};
7585
}
7686

7787
message WorkflowContractServiceUpdateResponse {

app/controlplane/internal/service/workflowcontract.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ func extractContractName(rawContract []byte, name string) (string, error) {
320320
return name, err
321321
}
322322

323-
// Try parsing as v2 Contract
323+
// Try parsing as v2 Contract
324324
v2Contract := &schemav1.CraftingSchemaV2{}
325325
if err := unmarshal.FromRaw(rawContract, format, v2Contract, true); err == nil {
326326
if v2Contract.GetMetadata() != nil {

app/controlplane/pkg/biz/workflowcontract.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,19 @@ var EmptyDefaultContract = &Contract{
215215
}
216216

217217
func (uc *WorkflowContractUseCase) Create(ctx context.Context, opts *WorkflowContractCreateOpts) (*WorkflowContract, error) {
218-
if opts.OrgID == "" || opts.Name == "" {
219-
return nil, NewErrValidationStr("organization and name are required")
218+
if opts.OrgID == "" {
219+
return nil, NewErrValidationStr("organization is required")
220220
}
221221

222222
orgUUID, err := uuid.Parse(opts.OrgID)
223223
if err != nil {
224224
return nil, err
225225
}
226226

227+
if opts.Name == "" {
228+
return nil, NewErrValidationStr("name is required")
229+
}
230+
227231
if err := ValidateIsDNS1123(opts.Name); err != nil {
228232
return nil, NewErrValidation(err)
229233
}
@@ -399,7 +403,8 @@ func (uc *WorkflowContractUseCase) ValidateContractPolicies(rawSchema []byte, to
399403
return NewErrValidation(err)
400404
}
401405

402-
if c.isV1Schema() {
406+
switch {
407+
case c.isV1Schema():
403408
// Handle v1 schema
404409
schema := c.Schema
405410
for _, att := range schema.GetPolicies().GetAttestation() {
@@ -417,7 +422,7 @@ func (uc *WorkflowContractUseCase) ValidateContractPolicies(rawSchema []byte, to
417422
return NewErrValidation(err)
418423
}
419424
}
420-
} else if c.isV2Schema() {
425+
case c.isV2Schema():
421426
// Handle v2 schema
422427
spec := c.Schemav2.GetSpec()
423428
if spec.GetPolicies() != nil {
@@ -437,7 +442,7 @@ func (uc *WorkflowContractUseCase) ValidateContractPolicies(rawSchema []byte, to
437442
return NewErrValidation(err)
438443
}
439444
}
440-
} else {
445+
default:
441446
return NewErrValidation(fmt.Errorf("invalid schema format"))
442447
}
443448

app/controlplane/pkg/data/workflowcontract.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/workflow"
3030
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/workflowcontract"
3131
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/workflowcontractversion"
32-
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/unmarshal"
3332

3433
"github.com/go-kratos/kratos/v2/log"
3534
"github.com/google/uuid"
@@ -358,12 +357,12 @@ func entContractVersionToBizContractVersion(w *ent.WorkflowContractVersion) (*bi
358357
// Scenario 2: contracts that have been updated after the introduction of the raw_body field will have the raw_body field populated
359358
// but we also want to keep the Body field populated for backward compatibility
360359
} else if len(w.Body) == 0 {
361-
schema := &schemav1.CraftingSchema{}
362-
err := unmarshal.FromRaw(w.RawBody, w.RawBodyFormat, schema, false)
360+
parsedContract, err := biz.UnmarshalAndValidateRawContract(w.RawBody, w.RawBodyFormat)
363361
if err != nil {
364362
return nil, fmt.Errorf("failed to unmarshal raw body: %w", err)
365363
}
366-
contract.Schema = schema
364+
contract.Schema = parsedContract.Schema
365+
contract.Schemav2 = parsedContract.Schemav2
367366
}
368367

369368
return &biz.WorkflowContractVersion{

0 commit comments

Comments
 (0)