Skip to content

Commit 49e347e

Browse files
authored
feat(argocd_application): add read-only status attribute (#295)
1 parent ce561fa commit 49e347e

File tree

6 files changed

+466
-21
lines changed

6 files changed

+466
-21
lines changed

argocd/resource_argocd_application.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func resourceArgoCDApplication() *schema.Resource {
4242
Optional: true,
4343
Default: true,
4444
},
45+
"status": applicationStatusSchema(),
4546
},
4647
SchemaVersion: 4,
4748
StateUpgraders: []schema.StateUpgrader{

argocd/resource_argocd_application_test.go

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ func TestAccArgoCDApplication(t *testing.T) {
3030
"spec.0.source.0.target_revision",
3131
"8.0.0",
3232
),
33+
resource.TestCheckResourceAttrSet(
34+
"argocd_application."+name,
35+
"status.0.%",
36+
),
3337
),
3438
},
3539
{
3640
ResourceName: "argocd_application." + name,
3741
ImportState: true,
3842
ImportStateVerify: true,
39-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
43+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
4044
},
4145
{
4246
// Update
@@ -67,8 +71,24 @@ func TestAccArgoCDApplication(t *testing.T) {
6771
"spec.0.source.0.target_revision",
6872
"9.4.1",
6973
),
74+
resource.TestCheckResourceAttr(
75+
"argocd_application."+name,
76+
"status.0.health.0.status",
77+
"Healthy",
78+
),
79+
resource.TestCheckResourceAttr(
80+
"argocd_application."+name,
81+
"status.0.sync.0.status",
82+
"Synced",
83+
),
7084
),
7185
},
86+
{
87+
ResourceName: "argocd_application." + name,
88+
ImportState: true,
89+
ImportStateVerify: true,
90+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
91+
},
7292
},
7393
})
7494
}
@@ -129,7 +149,7 @@ ingress:
129149
ResourceName: "argocd_application.helm",
130150
ImportState: true,
131151
ImportStateVerify: true,
132-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
152+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
133153
},
134154
},
135155
})
@@ -178,7 +198,7 @@ func TestAccArgoCDApplication_Kustomize(t *testing.T) {
178198
ResourceName: "argocd_application.kustomize",
179199
ImportState: true,
180200
ImportStateVerify: true,
181-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
201+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
182202
},
183203
},
184204
})
@@ -213,7 +233,7 @@ func TestAccArgoCDApplication_IgnoreDifferences(t *testing.T) {
213233
ResourceName: "argocd_application.ignore_differences",
214234
ImportState: true,
215235
ImportStateVerify: true,
216-
ImportStateVerifyIgnore: []string{"wait", "cascade"},
236+
ImportStateVerifyIgnore: []string{"wait", "cascade", "status"},
217237
},
218238
{
219239
Config: testAccArgoCDApplicationIgnoreDiffJQPathExpressions(
@@ -239,7 +259,7 @@ func TestAccArgoCDApplication_IgnoreDifferences(t *testing.T) {
239259
ResourceName: "argocd_application.ignore_differences_jqpe",
240260
ImportState: true,
241261
ImportStateVerify: true,
242-
ImportStateVerifyIgnore: []string{"wait", "cascade"},
262+
ImportStateVerifyIgnore: []string{"wait", "cascade", "status"},
243263
},
244264
},
245265
})
@@ -273,7 +293,7 @@ func TestAccArgoCDApplication_RevisionHistoryLimit(t *testing.T) {
273293
ResourceName: "argocd_application.revision_history_limit",
274294
ImportState: true,
275295
ImportStateVerify: true,
276-
ImportStateVerifyIgnore: []string{"wait", "cascade"},
296+
ImportStateVerifyIgnore: []string{"wait", "cascade", "status"},
277297
},
278298
},
279299
})
@@ -302,7 +322,7 @@ func TestAccArgoCDApplication_OptionalDestinationNamespace(t *testing.T) {
302322
ResourceName: "argocd_application.no_namespace",
303323
ImportState: true,
304324
ImportStateVerify: true,
305-
ImportStateVerifyIgnore: []string{"wait", "cascade"},
325+
ImportStateVerifyIgnore: []string{"wait", "cascade", "status"},
306326
},
307327
},
308328
})
@@ -387,7 +407,7 @@ func TestAccArgoCDApplication_DirectoryJsonnet(t *testing.T) {
387407
ResourceName: "argocd_application.directory",
388408
ImportState: true,
389409
ImportStateVerify: true,
390-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
410+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
391411
},
392412
},
393413
})
@@ -493,7 +513,7 @@ func TestAccArgoCDApplication_EmptyDirectory(t *testing.T) {
493513
ResourceName: "argocd_application.directory",
494514
ImportState: true,
495515
ImportStateVerify: true,
496-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
516+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
497517
},
498518
},
499519
})
@@ -525,7 +545,7 @@ func TestAccArgoCDApplication_DirectoryIncludeExclude(t *testing.T) {
525545
ResourceName: "argocd_application.directory",
526546
ImportState: true,
527547
ImportStateVerify: true,
528-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
548+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
529549
},
530550
},
531551
})
@@ -585,7 +605,7 @@ func TestAccArgoCDApplication_SyncPolicy(t *testing.T) {
585605
ResourceName: "argocd_application.sync_policy",
586606
ImportState: true,
587607
ImportStateVerify: true,
588-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
608+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
589609
},
590610
},
591611
})
@@ -937,7 +957,7 @@ func TestAccArgoCDApplication_CustomNamespace(t *testing.T) {
937957
ResourceName: "argocd_application.custom_namespace",
938958
ImportState: true,
939959
ImportStateVerify: true,
940-
ImportStateVerifyIgnore: []string{"wait", "cascade"},
960+
ImportStateVerifyIgnore: []string{"wait", "cascade", "status"},
941961
},
942962
},
943963
})
@@ -971,7 +991,7 @@ func TestAccArgoCDApplication_MultipleSources(t *testing.T) {
971991
ResourceName: "argocd_application.multiple_sources",
972992
ImportState: true,
973993
ImportStateVerify: true,
974-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
994+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
975995
},
976996
},
977997
})
@@ -1009,7 +1029,7 @@ func TestAccArgoCDApplication_HelmValuesFromExternalGitRepo(t *testing.T) {
10091029
ResourceName: "argocd_application.helm_values_external",
10101030
ImportState: true,
10111031
ImportStateVerify: true,
1012-
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version"},
1032+
ImportStateVerifyIgnore: []string{"wait", "cascade", "metadata.0.generation", "metadata.0.resource_version", "status"},
10131033
},
10141034
},
10151035
})

argocd/schema_application.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,6 +1814,210 @@ func resourceArgoCDApplicationV3() *schema.Resource {
18141814
}
18151815
}
18161816

1817+
func applicationStatusSchema() *schema.Schema {
1818+
return &schema.Schema{
1819+
Type: schema.TypeList,
1820+
Description: "Status information for the application. **Note**: this is not guaranteed to be up to date immediately after creating/updating an application unless `wait=true`.",
1821+
Computed: true,
1822+
Elem: &schema.Resource{
1823+
Schema: map[string]*schema.Schema{
1824+
"conditions": {
1825+
Type: schema.TypeList,
1826+
Description: "List of currently observed application conditions.",
1827+
Computed: true,
1828+
Elem: &schema.Resource{
1829+
Schema: map[string]*schema.Schema{
1830+
"message": {
1831+
Type: schema.TypeString,
1832+
Description: "Human-readable message indicating details about condition.",
1833+
Computed: true,
1834+
},
1835+
"last_transition_time": {
1836+
Type: schema.TypeString,
1837+
Description: "The time the condition was last observed.",
1838+
Computed: true,
1839+
},
1840+
"type": {
1841+
Type: schema.TypeString,
1842+
Description: "Application condition type.",
1843+
Computed: true,
1844+
},
1845+
},
1846+
},
1847+
},
1848+
"health": {
1849+
Type: schema.TypeList,
1850+
Description: "Application's current health status.",
1851+
Computed: true,
1852+
Elem: resourceApplicationHealthStatus(),
1853+
},
1854+
"operation_state": {
1855+
Type: schema.TypeList,
1856+
Description: "Information about any ongoing operations, such as a sync.",
1857+
Computed: true,
1858+
Elem: &schema.Resource{
1859+
Schema: map[string]*schema.Schema{
1860+
"finished_at": {
1861+
Type: schema.TypeString,
1862+
Description: "Time of operation completion.",
1863+
Computed: true,
1864+
},
1865+
"message": {
1866+
Type: schema.TypeString,
1867+
Description: "Any pertinent messages when attempting to perform operation (typically errors).",
1868+
Computed: true,
1869+
},
1870+
"phase": {
1871+
Type: schema.TypeString,
1872+
Description: "The current phase of the operation.",
1873+
Computed: true,
1874+
},
1875+
"retry_count": {
1876+
Type: schema.TypeString,
1877+
Description: "Count of operation retries.",
1878+
Computed: true,
1879+
},
1880+
"started_at": {
1881+
Type: schema.TypeString,
1882+
Description: "Time of operation start.",
1883+
Computed: true,
1884+
},
1885+
},
1886+
},
1887+
},
1888+
"reconciled_at": {
1889+
Type: schema.TypeString,
1890+
Description: "When the application state was reconciled using the latest git version.",
1891+
Computed: true,
1892+
},
1893+
"resources": {
1894+
Type: schema.TypeList,
1895+
Description: "List of Kubernetes resources managed by this application.",
1896+
Computed: true,
1897+
Elem: &schema.Resource{
1898+
Schema: map[string]*schema.Schema{
1899+
"group": {
1900+
Type: schema.TypeString,
1901+
Description: "The Kubernetes resource Group.",
1902+
Computed: true,
1903+
},
1904+
"health": {
1905+
Type: schema.TypeList,
1906+
Description: "Resource health status.",
1907+
Computed: true,
1908+
Elem: resourceApplicationHealthStatus(),
1909+
},
1910+
"kind": {
1911+
Type: schema.TypeString,
1912+
Description: "The Kubernetes resource Kind.",
1913+
Computed: true,
1914+
},
1915+
"hook": {
1916+
Type: schema.TypeBool,
1917+
Description: "Indicates whether or not this resource has a hook annotation.",
1918+
Computed: true,
1919+
},
1920+
"name": {
1921+
Type: schema.TypeString,
1922+
Description: "The Kubernetes resource Name.",
1923+
Computed: true,
1924+
},
1925+
"namespace": {
1926+
Type: schema.TypeString,
1927+
Description: "The Kubernetes resource Namespace.",
1928+
Computed: true,
1929+
},
1930+
"requires_pruning": {
1931+
Type: schema.TypeBool,
1932+
Description: "Indicates if the resources requires pruning or not.",
1933+
Computed: true,
1934+
},
1935+
"status": {
1936+
Type: schema.TypeString,
1937+
Description: "Resource sync status.",
1938+
Computed: true,
1939+
},
1940+
"sync_wave": {
1941+
Type: schema.TypeString,
1942+
Description: "Sync wave.",
1943+
Computed: true,
1944+
},
1945+
"version": {
1946+
Type: schema.TypeString,
1947+
Description: "The Kubernetes resource Version.",
1948+
Computed: true,
1949+
},
1950+
},
1951+
},
1952+
},
1953+
"summary": {
1954+
Type: schema.TypeList,
1955+
Description: "List of URLs and container images used by this application.",
1956+
Computed: true,
1957+
Elem: &schema.Resource{
1958+
Schema: map[string]*schema.Schema{
1959+
"external_urls": {
1960+
Type: schema.TypeList,
1961+
Description: "All external URLs of application child resources.",
1962+
Computed: true,
1963+
Elem: schema.TypeString,
1964+
},
1965+
"images": {
1966+
Type: schema.TypeList,
1967+
Description: "All images of application child resources.",
1968+
Computed: true,
1969+
Elem: schema.TypeString,
1970+
},
1971+
},
1972+
},
1973+
},
1974+
"sync": {
1975+
Type: schema.TypeList,
1976+
Description: "Application's current sync status",
1977+
Computed: true,
1978+
Elem: &schema.Resource{
1979+
Schema: map[string]*schema.Schema{
1980+
"revision": {
1981+
Type: schema.TypeString,
1982+
Description: "Information about the revision the comparison has been performed to.",
1983+
Computed: true,
1984+
},
1985+
"revisions": {
1986+
Type: schema.TypeList,
1987+
Description: "Information about the revision(s) the comparison has been performed to.",
1988+
Computed: true,
1989+
Elem: schema.TypeString,
1990+
},
1991+
"status": {
1992+
Type: schema.TypeString,
1993+
Description: "Sync state of the comparison.",
1994+
Computed: true,
1995+
},
1996+
},
1997+
},
1998+
},
1999+
},
2000+
},
2001+
}
2002+
}
2003+
2004+
func resourceApplicationHealthStatus() *schema.Resource {
2005+
return &schema.Resource{
2006+
Schema: map[string]*schema.Schema{
2007+
"message": {
2008+
Type: schema.TypeString,
2009+
Description: "Human-readable informational message describing the health status.",
2010+
Computed: true,
2011+
},
2012+
"status": {
2013+
Type: schema.TypeString,
2014+
Description: "Status code of the application or resource.",
2015+
Computed: true,
2016+
},
2017+
},
2018+
}
2019+
}
2020+
18172021
func resourceArgoCDApplicationStateUpgradeV0(_ context.Context, rawState map[string]interface{}, _ interface{}) (map[string]interface{}, error) {
18182022
_spec, ok := rawState["spec"].([]interface{})
18192023
if !ok || len(_spec) == 0 {

0 commit comments

Comments
 (0)