Rundeckの実行ログを削除する（Windows vbscript）

# Rundeckの実行ログを削除する
OSSのジョブ管理ツール Rundeck で過去の実行結果を削除する vbscript を作成しました。（Rundeck のAPI コールで実現）

OSSのジョブ管理ツール Rundeck で過去の実行結果を削除する方法は以下がありそうでした
* 画面から削除する（但し１ページ毎にしか操作できず）
* [Rundeck cli を使う](https://docs.rundeck.com/docs/rd-cli/)
* [python のプログラムで削除する（API CALLする）](https://github.com/danifr/rundeck-scripts/blob/master/py_scripts/deleteoldlogs.py)

Windowsサーバだとわざわざお掃除のためだけの 実行環境を整えたくなくて、python プログラムを参考に VbScriptを作りました

```visualbasic:deletelogs.vbs
Option Explicit
'*********************************************************************
'* Rundeck ジョブ削除
'*********************************************************************
'*  全てのプロジェクト配下の全てのジョブの実行結果の終了日時が
'*  保持期限（EXP_DAYS）を過ぎた結果を削除する（API CALL）
'*
'*    getProjectNames
'*    listProjects
'*
'*    getJobIds
'*    listJobsInProject
'*
'*    getExecutionsForDetete
'*    listExecutionsInJob
'*
'*    deleteExecution
'*
'*********************************************************************
Const RD_SERVER = "http://127.0.0.1"
Const RD_PORT = "4440"
Const RD_API_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Const EXP_DAYS = 30

'*********************************************************************
'* メイン
'*********************************************************************

    Dim oHttpRequest
    Dim objxml
    Dim projects
    Dim project 
    Dim jobids
    Dim jobid 
    Dim execids
    Dim execid
    Dim del_dt

    '削除基準日
    del_dt = DateAdd("d", EXP_DAYS * -1, Now())
    WScript.echo "削除基準日：" & del_dt

    Set oHttpRequest = WScript.CreateObject("MSXML2.XMLHTTP.3.0")

    ' 存在するプロジェクトを取得し、名称のリストを
    projects = getProjectNames(listProjects())

   ' プロジェクトごとに JOBIDリストを取得
    For Each project In projects
       WScript.Echo "project:" & project
 
       jobids = getJobIDs(listJobsInProject(project))

       For Each jobid In jobids
           WScript.echo "jobid:" & jobid
           
           execids = getExecutionsForDetete(listExecutionsInJob(jobid), del_dt)
           For Each execid In execids
               Call deleteExecution(execid)
           Next
       Next
    Next

    Set oHttpRequest = Nothing


'*********************************************************************
'* 応答文字列（XML）より、プロジェクト名一覧取得
'*********************************************************************
Private Function getProjectNames(xmlText)
    Dim project_names
    Dim objDOM
    Dim objRes
    Dim nodeList
    Dim node
    Set objDOM = WScript.CreateObject("MSXML2.DOMDocument")
    'XML レスポンスデータ解析
    objRes = objDOM.loadXML(xmlText)
    If objRes Then
        ' プロジェクトのリストを取得
        Set nodeList = objDOM.documentElement.selectNodes("/projects/project/name")
        project_names = Array()
        For Each node In nodeList
            Redim Preserve project_names( UBound(project_names) + 1 )
            project_names( UBound(project_names)) = node.text
        Next

    Else 
       wscript.echo objDOM.parseError.reason
    End If 
    
    getProjectNames = project_names

End Function


'*********************************************************************
'*  応答文字列（XML）より、JOBID一覧取得
'*********************************************************************
Private Function getJobIDs(xmlText)
    Dim jobids
    Dim objDOM
    Dim objRes
    Dim nodeList
    Dim node
    Set objDOM = WScript.CreateObject("MSXML2.DOMDocument")
    'XML レスポンスデータ解析
    objRes = objDOM.loadXML(xmlText)
    If objRes Then
        ' プロジェクトのリストを取得
        Set nodeList = objDOM.documentElement.selectNodes("/jobs/job")
        jobids = Array()
        For Each node In nodeList
            Redim Preserve jobids( UBound(jobids) + 1 )
            jobids( UBound(jobids)) = node.GetAttribute("id")
        Next

    Else 
       wscript.echo objDOM.parseError.reason
    End If 
    
    getJobIDs = jobids

End Function


'*********************************************************************
'*  応答文字列（XML）より、保持期間切れ execution id の一覧取得
'*********************************************************************
Private Function getExecutionsForDetete(xmlText, del_dt)
    Dim execids
    Dim objDOM
    Dim objRes
    Dim nodeList
    Dim node
    Dim dtList
    Dim dt
    Dim end_time
    Dim exp_time
    
    Set objDOM = WScript.CreateObject("MSXML2.DOMDocument")
    'XML レスポンスデータ解析
    objRes = objDOM.loadXML(xmlText)
    If objRes Then
        ' プロジェクトのリストを取得
        Set nodeList = objDOM.documentElement.selectNodes("/executions/execution")
        execids = Array()
        For Each node In nodeList

            Set dtList = node.selectNodes("date-ended")
            For Each dt In dtList
                end_time = dt.GetAttribute("unixtime") * 1
                exp_time = DateDiff("s", "1970/1/1 0:00:00",DateAdd("h",-9, del_dt)) * 1000
                ' 保持期間を過ぎていたらリストに入れる
                If exp_time > end_time Then
                    Redim Preserve execids( UBound(execids) + 1 )
                    execids( UBound(execids)) = node.GetAttribute("id")
                    Exit For
                End If
            Next
        Next

    Else 
       wscript.echo objDOM.parseError.reason
    End If 
    
    getExecutionsForDetete = execids

End Function


'*********************************************************************
'* プロジェクト一覧をAPIで取得
'*********************************************************************
Private Function listProjects
    Dim strURL
    strURL = RD_SERVER & ":" & RD_PORT & "/api/14/projects"

    oHttpRequest.Open "GET", strURL, False
    oHttpRequest.setRequestHeader "Content-Type", "application/json" 
    oHttpRequest.setRequestHeader "X-Rundeck-Auth-Token", RD_API_TOKEN

    oHttpRequest.Send

    listProjects =  ResponseToText(oHttpRequest.responseBody)

End Function


'*********************************************************************
'* プロジェクトのジョブID一覧を取得
'*********************************************************************
Private Function listJobsInProject(project)
    Dim strURL
    strURL = RD_SERVER & ":" & RD_PORT & "/api/14/project/"
    strURL = strURL & project & "/jobs"
    oHttpRequest.Open "GET", strURL, False
    oHttpRequest.setRequestHeader "Content-Type", "application/json" 
    oHttpRequest.setRequestHeader "X-Rundeck-Auth-Token", RD_API_TOKEN

    oHttpRequest.Send

    listJobsInProject =  ResponseToText(oHttpRequest.responseBody)

End Function


'*********************************************************************
'* 実行結果ID一覧を取得
'*********************************************************************
Private Function listExecutionsInJob(jobid)
    Dim strURL
    strURL = RD_SERVER & ":" & RD_PORT & "/api/14/job/"
    strURL = strURL & jobid & "/executions"
    oHttpRequest.Open "GET", strURL, False
    oHttpRequest.setRequestHeader "Content-Type", "application/json" 
    oHttpRequest.setRequestHeader "X-Rundeck-Auth-Token", RD_API_TOKEN

    oHttpRequest.Send

    listExecutionsInJob = ResponseToText(oHttpRequest.responseBody)

End Function


'*********************************************************************
'* レスポンスの内容を文字コード変換して読み込む
'*********************************************************************
Private Function ResponseToText(body)

    Dim stm
    Dim strResult
    Set stm = CreateObject("ADODB.Stream")
    stm.Type = 1   'バイナリモード
    stm.Open
    stm.Write body  'バイナリを書き込み
    stm.Position = 0  '先頭に戻してから
    stm.Type = 2   'テキストモードに変更
    stm.Charset = "shift_jis"
    strResult = stm.ReadText(-1)   'データ全体を読み込む
    stm.Close
    ResponseToText =  strResult

End Function


'*********************************************************************
'* 実行結果を削除する
'*********************************************************************
Private Sub deleteExecution(execid)
    Dim strURL
    strURL = RD_SERVER & ":" & RD_PORT & "/api/14/execution/"
    strURL = strURL & execid 
    oHttpRequest.Open "DELETE", strURL, False
    oHttpRequest.setRequestHeader "Content-Type", "application/json" 
    oHttpRequest.setRequestHeader "X-Rundeck-Auth-Token", RD_API_TOKEN

    oHttpRequest.Send
    Wscript.echo "delete:" & execid

End Sub



```