Skip to content

Commit e583e93

Browse files
committed
Exported project level jira and snow settings
1 parent d3678a9 commit e583e93

File tree

5 files changed

+229
-26
lines changed

5 files changed

+229
-26
lines changed

cmd/internal/converters/project_converter.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,14 @@ func (c *ProjectConverter) toHcl(project octopus.Project, recursive bool, lookup
499499
terraformResource := terraform.TerraformProject{
500500
Type: octopusdeployProjectResourceType,
501501
Name: projectName,
502-
ResourceName: resourceName,
502+
Count: nil,
503503
Id: strutil.InputPointerIfEnabled(c.IncludeIds, &project.Id),
504504
SpaceId: strutil.InputIfEnabled(c.IncludeSpaceInPopulation, dependencies.GetResourceDependency("Spaces", project.SpaceId)),
505+
ResourceName: resourceName,
505506
AutoCreateRelease: nil,
506507
DefaultGuidedFailureMode: project.DefaultGuidedFailureMode,
507508
DefaultToSkipIfAlreadyInstalled: project.DefaultToSkipIfAlreadyInstalled,
509+
Description: nil,
508510
DiscreteChannelRelease: project.DiscreteChannelRelease,
509511
IsDisabled: project.IsDisabled,
510512
IsVersionControlled: versionControlled,
@@ -517,7 +519,10 @@ func (c *ProjectConverter) toHcl(project octopus.Project, recursive bool, lookup
517519
GitLibraryPersistenceSettings: c.convertLibraryGitPersistence(project, projectName, dependencies),
518520
GitAnonymousPersistenceSettings: c.convertAnonymousGitPersistence(project, projectName),
519521
GitUsernamePasswordPersistenceSettings: c.convertUsernamePasswordGitPersistence(project, projectName),
522+
Lifecycle: nil,
520523
VersioningStrategy: versioningStrategy,
524+
JiraServiceManagementExtensionSettings: c.convertJiraSettings(project),
525+
ServicenowExtensionSettings: c.convertServiceNowSettings(project),
521526
}
522527

523528
// There is no point ignoring changes for stateless exports
@@ -978,6 +983,61 @@ func (c *ProjectConverter) convertAnonymousGitPersistence(project octopus.Projec
978983
}
979984
}
980985

986+
func (c *ProjectConverter) convertJiraSettings(project octopus.Project) *terraform.TerraformProjectJiraServiceManagementExtensionSettings {
987+
if project.ExtensionSettings == nil {
988+
return nil
989+
}
990+
991+
jiraExtension := lo.Filter(project.ExtensionSettings, func(item octopus.ExtensionSetting, index int) bool {
992+
return item.ExtensionId == "jiraservicemanagement-integration"
993+
})
994+
995+
if len(jiraExtension) == 0 {
996+
return nil
997+
}
998+
999+
connectionId := maputil.ValueOrStringDefault(jiraExtension[0].Values, "JsmConnectionId", "")
1000+
1001+
if connectionId == "" {
1002+
return nil
1003+
}
1004+
1005+
return &terraform.TerraformProjectJiraServiceManagementExtensionSettings{
1006+
ConnectionId: connectionId,
1007+
IsEnabled: maputil.ValueOrBoolDefault(jiraExtension[0].Values, "JsmChangeControlled", false),
1008+
ServiceDeskProjectName: maputil.ValueOrStringDefault(jiraExtension[0].Values, "ServiceDeskProjectName", ""),
1009+
}
1010+
}
1011+
1012+
func (c *ProjectConverter) convertServiceNowSettings(project octopus.Project) *terraform.TerraformProjectServicenowExtensionSettings {
1013+
if project.ExtensionSettings == nil {
1014+
return nil
1015+
}
1016+
1017+
snowExtension := lo.Filter(project.ExtensionSettings, func(item octopus.ExtensionSetting, index int) bool {
1018+
return item.ExtensionId == "servicenow-integration"
1019+
})
1020+
1021+
if len(snowExtension) == 0 {
1022+
return nil
1023+
}
1024+
1025+
connectionId := maputil.ValueOrStringDefault(snowExtension[0].Values, "ServiceNowConnectionId", "")
1026+
1027+
if connectionId == "" {
1028+
return nil
1029+
}
1030+
1031+
return &terraform.TerraformProjectServicenowExtensionSettings{
1032+
ConnectionId: connectionId,
1033+
IsEnabled: maputil.ValueOrBoolDefault(snowExtension[0].Values, "ServiceNowChangeControlled", false),
1034+
// The TF provider exposes a boolean, but the API returns a string with at least 3 possible values.
1035+
// We can't capture the settings here.
1036+
IsStateAutomaticallyTransitioned: false,
1037+
StandardChangeTemplateName: strutil.NilIfEmpty(maputil.ValueOrStringDefault(snowExtension[0].Values, "StandardChangeTemplateName", "")),
1038+
}
1039+
}
1040+
9811041
func (c *ProjectConverter) convertUsernamePasswordGitPersistence(project octopus.Project, projectName string) *terraform.TerraformGitUsernamePasswordPersistenceSettings {
9821042
if project.PersistenceSettings.Credentials.Type != "UsernamePassword" || c.ExcludeCaCProjectSettings {
9831043
return nil

cmd/internal/maputil/map_util.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,37 @@ func ToStringAnyMap(input map[string]string) map[string]any {
1919
return any(value)
2020
})
2121
}
22+
23+
func ValueOrStringDefault(input map[string]any, key string, defaultValue string) string {
24+
if input == nil {
25+
return defaultValue
26+
}
27+
28+
value, exists := input[key]
29+
if !exists {
30+
return defaultValue
31+
}
32+
33+
if value == nil {
34+
return defaultValue
35+
}
36+
37+
return value.(string)
38+
}
39+
40+
func ValueOrBoolDefault(input map[string]any, key string, defaultValue bool) bool {
41+
if input == nil {
42+
return defaultValue
43+
}
44+
45+
value, exists := input[key]
46+
if !exists {
47+
return defaultValue
48+
}
49+
50+
if value == nil {
51+
return defaultValue
52+
}
53+
54+
return value.(bool)
55+
}

cmd/internal/maputil/map_util_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,92 @@ func TestNullIfEmptyMap(t *testing.T) {
4545
})
4646
}
4747
}
48+
49+
func TestValueOrStringDefault(t *testing.T) {
50+
tests := []struct {
51+
name string
52+
input map[string]any
53+
key string
54+
defaultValue string
55+
expectedValue string
56+
}{
57+
{
58+
name: "Nil input returns default value",
59+
input: nil,
60+
key: "key",
61+
defaultValue: "default",
62+
expectedValue: "default",
63+
},
64+
{
65+
name: "Key exists in map",
66+
input: map[string]any{"key": "value"},
67+
key: "key",
68+
defaultValue: "default",
69+
expectedValue: "value",
70+
},
71+
{
72+
name: "Key does not exist in map",
73+
input: map[string]any{"other_key": "value"},
74+
key: "key",
75+
defaultValue: "default",
76+
expectedValue: "default",
77+
},
78+
}
79+
80+
for _, tt := range tests {
81+
t.Run(tt.name, func(t *testing.T) {
82+
result := ValueOrStringDefault(tt.input, tt.key, tt.defaultValue)
83+
if result != tt.expectedValue {
84+
t.Errorf("expected %s, got %s", tt.expectedValue, result)
85+
}
86+
})
87+
}
88+
}
89+
90+
func TestValueOrBoolDefault(t *testing.T) {
91+
tests := []struct {
92+
name string
93+
input map[string]any
94+
key string
95+
defaultValue bool
96+
expectedValue bool
97+
}{
98+
{
99+
name: "Nil input returns default value",
100+
input: nil,
101+
key: "key",
102+
defaultValue: true,
103+
expectedValue: true,
104+
},
105+
{
106+
name: "Key exists in map with true value",
107+
input: map[string]any{"key": true},
108+
key: "key",
109+
defaultValue: false,
110+
expectedValue: true,
111+
},
112+
{
113+
name: "Key exists in map with false value",
114+
input: map[string]any{"key": false},
115+
key: "key",
116+
defaultValue: true,
117+
expectedValue: false,
118+
},
119+
{
120+
name: "Key does not exist in map",
121+
input: map[string]any{"other_key": true},
122+
key: "key",
123+
defaultValue: false,
124+
expectedValue: false,
125+
},
126+
}
127+
128+
for _, tt := range tests {
129+
t.Run(tt.name, func(t *testing.T) {
130+
result := ValueOrBoolDefault(tt.input, tt.key, tt.defaultValue)
131+
if result != tt.expectedValue {
132+
t.Errorf("expected %t, got %t", tt.expectedValue, result)
133+
}
134+
})
135+
}
136+
}

cmd/internal/model/octopus/octopus_project.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type Project struct {
5959
IncludedLibraryVariableSetIds []string
6060
PersistenceSettings PersistenceSettings
6161
VersioningStrategy VersioningStrategy
62-
// Todo: add service now and jira settings
62+
ExtensionSettings []ExtensionSetting
6363
}
6464

6565
func (p *Project) GetParentId() *string {
@@ -108,3 +108,8 @@ type DonorPackage struct {
108108
DeploymentAction *string
109109
PackageReference *string
110110
}
111+
112+
type ExtensionSetting struct {
113+
ExtensionId string
114+
Values map[string]any
115+
}

cmd/internal/model/terraform/terraform_project.go

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
package terraform
22

33
type TerraformProject struct {
4-
Type string `hcl:"type,label"`
5-
Name string `hcl:"name,label"`
6-
Count *string `hcl:"count"`
7-
Id *string `hcl:"id"`
8-
SpaceId *string `hcl:"space_id"`
9-
ResourceName string `hcl:"name"`
10-
AutoCreateRelease *bool `hcl:"auto_create_release"`
11-
DefaultGuidedFailureMode *string `hcl:"default_guided_failure_mode"`
12-
DefaultToSkipIfAlreadyInstalled bool `hcl:"default_to_skip_if_already_installed"`
13-
Description *string `hcl:"description"`
14-
DiscreteChannelRelease bool `hcl:"discrete_channel_release"`
15-
IsDisabled bool `hcl:"is_disabled"`
16-
IsVersionControlled bool `hcl:"is_version_controlled"`
17-
LifecycleId string `hcl:"lifecycle_id"`
18-
ProjectGroupId string `hcl:"project_group_id"`
19-
IncludedLibraryVariableSets []string `hcl:"included_library_variable_sets"`
20-
TenantedDeploymentParticipation *string `hcl:"tenanted_deployment_participation"`
21-
Template []TerraformTemplate `hcl:"template,block"`
22-
ConnectivityPolicy *TerraformConnectivityPolicy `hcl:"connectivity_policy,block"`
23-
GitLibraryPersistenceSettings *TerraformGitLibraryPersistenceSettings `hcl:"git_library_persistence_settings,block"`
24-
GitAnonymousPersistenceSettings *TerraformGitAnonymousPersistenceSettings `hcl:"git_anonymous_persistence_settings,block"`
25-
GitUsernamePasswordPersistenceSettings *TerraformGitUsernamePasswordPersistenceSettings `hcl:"git_username_password_persistence_settings,block"`
26-
Lifecycle *TerraformLifecycleMetaArgument `hcl:"lifecycle,block"`
27-
VersioningStrategy *TerraformVersioningStrategy `hcl:"versioning_strategy,block"`
4+
Type string `hcl:"type,label"`
5+
Name string `hcl:"name,label"`
6+
Count *string `hcl:"count"`
7+
Id *string `hcl:"id"`
8+
SpaceId *string `hcl:"space_id"`
9+
ResourceName string `hcl:"name"`
10+
AutoCreateRelease *bool `hcl:"auto_create_release"`
11+
DefaultGuidedFailureMode *string `hcl:"default_guided_failure_mode"`
12+
DefaultToSkipIfAlreadyInstalled bool `hcl:"default_to_skip_if_already_installed"`
13+
Description *string `hcl:"description"`
14+
DiscreteChannelRelease bool `hcl:"discrete_channel_release"`
15+
IsDisabled bool `hcl:"is_disabled"`
16+
IsVersionControlled bool `hcl:"is_version_controlled"`
17+
LifecycleId string `hcl:"lifecycle_id"`
18+
ProjectGroupId string `hcl:"project_group_id"`
19+
IncludedLibraryVariableSets []string `hcl:"included_library_variable_sets"`
20+
TenantedDeploymentParticipation *string `hcl:"tenanted_deployment_participation"`
21+
Template []TerraformTemplate `hcl:"template,block"`
22+
ConnectivityPolicy *TerraformConnectivityPolicy `hcl:"connectivity_policy,block"`
23+
GitLibraryPersistenceSettings *TerraformGitLibraryPersistenceSettings `hcl:"git_library_persistence_settings,block"`
24+
GitAnonymousPersistenceSettings *TerraformGitAnonymousPersistenceSettings `hcl:"git_anonymous_persistence_settings,block"`
25+
GitUsernamePasswordPersistenceSettings *TerraformGitUsernamePasswordPersistenceSettings `hcl:"git_username_password_persistence_settings,block"`
26+
Lifecycle *TerraformLifecycleMetaArgument `hcl:"lifecycle,block"`
27+
VersioningStrategy *TerraformVersioningStrategy `hcl:"versioning_strategy,block"`
28+
JiraServiceManagementExtensionSettings *TerraformProjectJiraServiceManagementExtensionSettings `hcl:"jira_service_management_extension_settings,block"`
29+
ServicenowExtensionSettings *TerraformProjectServicenowExtensionSettings `hcl:"servicenow_extension_settings,block"`
30+
}
31+
32+
type TerraformProjectServicenowExtensionSettings struct {
33+
ConnectionId string `hcl:"connection_id"`
34+
IsEnabled bool `hcl:"is_enabled"`
35+
IsStateAutomaticallyTransitioned bool `hcl:"is_state_automatically_transitioned"`
36+
StandardChangeTemplateName *string `hcl:"standard_change_template_name"`
37+
}
38+
39+
type TerraformProjectJiraServiceManagementExtensionSettings struct {
40+
ConnectionId string `hcl:"connection_id"`
41+
IsEnabled bool `hcl:"is_enabled"`
42+
ServiceDeskProjectName string `hcl:"service_desk_project_name"`
2843
}
2944

3045
type TerraformVersioningStrategy struct {

0 commit comments

Comments
 (0)